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
1874640895fafbb90a6630a6a91b80da0a7cff229cHenrik Kjellander#include "webrtc/modules/audio_coding/codecs/isac/fix/include/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"
2998f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/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 */
41dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingstatic void InitializeDecoderBitstream(size_t 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;
210fa65c851feeaebdfd514cacd453fd585b069b06dkma@webrtc.org  WebRtcIsacfix_AllpassFilter2FixDec16 =
211fa65c851feeaebdfd514cacd453fd585b069b06dkma@webrtc.org      WebRtcIsacfix_AllpassFilter2FixDec16Neon;
21223da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org  WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1Neon;
21323da8622c04ac843f7912dd33b4ad55f41422119kma@webrtc.org  WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2Neon;
214715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org}
215715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org#endif
216715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org
217715509890ca462c70c6d20d04b084b3d068249f7kma@webrtc.org/****************************************************************************
218919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org * WebRtcIsacfix_InitMIPS(...)
219919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org *
220919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org * This function initializes function pointers for MIPS platform.
221919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org */
222919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
223919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS32_LE)
224919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.orgstatic void WebRtcIsacfix_InitMIPS(void) {
225919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrMIPS;
226919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopMIPS;
227ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeMIPS;
228ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecMIPS;
229f86b2625889b065ccf67e580a8456f0b5e42b261andrew@webrtc.org  WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1MIPS;
230f86b2625889b065ccf67e580a8456f0b5e42b261andrew@webrtc.org  WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2MIPS;
231919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#if defined(MIPS_DSP_R1_LE)
232919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org  WebRtcIsacfix_AllpassFilter2FixDec16 =
233919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org      WebRtcIsacfix_AllpassFilter2FixDec16MIPS;
234ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_HighpassFilterFixDec32 =
235ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org      WebRtcIsacfix_HighpassFilterFixDec32MIPS;
236ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org#endif
237ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org#if defined(MIPS_DSP_R2_LE)
238ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org  WebRtcIsacfix_CalculateResidualEnergy =
239ceafa8cce9554b0777aa3cbdf70236e1fbabb414andrew@webrtc.org      WebRtcIsacfix_CalculateResidualEnergyMIPS;
240919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
241919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org}
242919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org#endif
243919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
244608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwibergstatic void InitFunctionPointers(void) {
245608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
246608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
247608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_CalculateResidualEnergy =
248608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg      WebRtcIsacfix_CalculateResidualEnergyC;
249608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
250608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
251608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
252608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
253608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
254608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
255608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg
256608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg#ifdef WEBRTC_DETECT_NEON
257608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
258608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg    WebRtcIsacfix_InitNeon();
259608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  }
260608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg#elif defined(WEBRTC_HAS_NEON)
261608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_InitNeon();
262608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg#endif
263608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg
264608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg#if defined(MIPS32_LE)
265608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  WebRtcIsacfix_InitMIPS();
266608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg#endif
267608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg}
268608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg
269919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org/****************************************************************************
270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_EncoderInit(...)
271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
272470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function initializes a ISAC instance prior to the encoder calls.
273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - CodingMode        : 0 -> Bit rate and frame length are automatically
277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 adjusted to available bandwidth on
278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 transmission channel.
279470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            1 -> User sets a frame length and a target bit
280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 rate which is taken as the maximum short-term
281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                 average bit rate.
282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2870946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
2880946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                  int16_t  CodingMode)
289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int k;
2910946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t statusInit;
292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  statusInit = 0;
295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* flag encoder init */
299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->initflag |= 2;
300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (CodingMode == 0)
302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Adaptive mode */
303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.new_framelength  = INITIAL_FRAMESAMPLES;
304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else if (CodingMode == 1)
305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Instantaneous mode */
306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.new_framelength = 480;    /* default for I-mode */
307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else {
308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE;
309470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    statusInit = -1;
310470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->CodingMode = CodingMode;
313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj);
315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj);
316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj);
317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj);
318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj);
320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.buffer_index   = 0;
323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.frame_nb    = 0;
324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.BottleNeck      = 32000; /* default for I-mode */
325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.MaxDelay    = 10;    /* default for I-mode */
326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.current_framesamples = 0;
327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.s2nr     = 0;
328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.MaxBits    = 0;
329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.bitstr_seed   = 4447;
330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.payloadLimitBytes30  = STREAM_MAXW16_30MS << 1;
331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.payloadLimitBytes60  = STREAM_MAXW16_60MS << 1;
332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.maxPayloadBytes      = STREAM_MAXW16_60MS << 1;
333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.maxRateInBytes       = STREAM_MAXW16_30MS << 1;
334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.enforceFrameSize     = 0;
335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Init the bistream data area to zero */
337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0; k<STREAM_MAXW16_60MS; k++){
338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0;
339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3417796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj);
343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
345608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  InitFunctionPointers();
346919914d71becdf4ef3a322d0af0d997c7f458e7candrew@webrtc.org
347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return statusInit;
348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3500552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org/* Read the given number of bytes of big-endian 16-bit integers from |src| and
3510552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   write them to |dest| in host endian. If |nbytes| is odd, the number of
3520552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   output elements is rounded up, and the least significant byte of the last
3530552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   element is set to 0. */
3540552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.orgstatic void read_be16(const uint8_t* src, size_t nbytes, uint16_t* dest) {
3550552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  size_t i;
3560552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  for (i = 0; i < nbytes / 2; ++i)
3570552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[i] = src[2 * i] << 8 | src[2 * i + 1];
3580552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  if (nbytes % 2 == 1)
3590552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[nbytes / 2] = src[nbytes - 1] << 8;
3600552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org}
3610552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org
3620552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org/* Read the given number of bytes of host-endian 16-bit integers from |src| and
3630552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   write them to |dest| in big endian. If |nbytes| is odd, the number of source
3640552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   elements is rounded up (but only the most significant byte of the last
3650552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   element is used), and the number of output bytes written will be
3660552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org   nbytes + 1. */
3670552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.orgstatic void write_be16(const uint16_t* src, size_t nbytes, uint8_t* dest) {
3680552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  size_t i;
3690552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  for (i = 0; i < nbytes / 2; ++i) {
3700552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[2 * i] = src[i] >> 8;
3710552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[2 * i + 1] = src[i];
3720552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  }
3730552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  if (nbytes % 2 == 1) {
3740552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[nbytes - 1] = src[nbytes / 2] >> 8;
3750552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org    dest[nbytes] = 0;
3760552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  }
3770552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org}
3780552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org
379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Encode(...)
381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function encodes 10ms frame(s) and inserts it into a package.
383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input speech length has to be 160 samples (10ms). The encoder buffers those
384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - speechIn          : input speech vector.
390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : the encoded data vector
393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value:
395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : >0 - Length (in bytes) of coded data
396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          :  0 - The buffer didn't reach the chosen framesize
397470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            so it keeps buffering speech samples.
398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : -1 - Error
399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
401aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kastingint WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
402aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         const int16_t    *speechIn,
403aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         uint8_t* encoded)
404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
406aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting  int stream_len;
407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
4180946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechIn,
4190946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->ISACenc_obj,
4200946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->bwestimator_obj,
4210946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        ISAC_inst->CodingMode);
422470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (stream_len<0) {
423aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->errorcode = -(int16_t)stream_len;
424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
427b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting  write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, (size_t)stream_len,
428b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting             encoded);
429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_len;
430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_EncodeNb(...)
438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * it into a package. Input speech length has to be 80 samples (10ms). The encoder
441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * interpolates into wide-band (16 kHz sampling) buffers those
442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4457796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
4467796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com *
447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - speechIn          : input speech vector.
450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : the encoded data vector
453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value:
455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : >0 - Length (in bytes) of coded data
456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          :  0 - The buffer didn't reach the chosen framesize
457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            so it keeps buffering speech samples.
458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : -1 - Error
459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
4607796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
4610946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
4620946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                               const int16_t    *speechIn,
4630946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                               int16_t          *encoded)
464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
4660946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t stream_len;
4670946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t speechInWB[FRAMESAMPLES_10ms];
4680946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t Vector_Word16_1[FRAMESAMPLES_10ms/2];
4690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t Vector_Word16_2[FRAMESAMPLES_10ms/2];
470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int k;
472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
482470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Oversample to WB */
486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Form polyphase signals, and compensate for DC offset */
488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<FRAMESAMPLES_10ms/2;k++) {
489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_1[k] = speechIn[k] + 1;
490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    Vector_Word16_2[k] = speechIn[k];
491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_FilterAndCombine2(Vector_Word16_1, Vector_Word16_2, speechInWB, &ISAC_inst->ISACenc_obj.interpolatorstr_obj, FRAMESAMPLES_10ms);
493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Encode WB signal */
4960946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechInWB,
4970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->ISACenc_obj,
4980946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        &ISAC_inst->bwestimator_obj,
4990946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        ISAC_inst->CodingMode);
500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (stream_len<0) {
501470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = - stream_len;
502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5050552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream,
5060552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org             stream_len,
5070552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org             (uint8_t*)encoded);
508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_len;
509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
5107796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#endif  /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetNewBitStream(...)
515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns encoded data, with the recieved bwe-index in the
517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * stream. It should always return a complete packet, i.e. only called once
518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * even for 60 msec frames
519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - bweIndex          : index of bandwidth estimate to put in new bitstream
523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : the encoded data vector
526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value:
528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : >0 - Length (in bytes) of coded data
529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                          : -1 - Error
530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5320946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
5330946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                      int16_t      bweIndex,
5340946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                      float              scale,
5351172988c794d15706b4c951dcbaa57b11221d225kwiberg@webrtc.org                                      uint8_t* encoded)
536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
5380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t stream_len;
539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to rela structure */
541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
542470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj,
551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                              bweIndex,
552ebb2744337bf26c8e02197da467b14a95df6c718turajs@google.com                                              scale);
553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (stream_len<0) {
554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = - stream_len;
555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5580552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len, encoded);
559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_len;
560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecoderInit(...)
566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function initializes a ISAC instance prior to the decoder calls.
568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5734376648df021fd82f25a38694e33678f802d06eaKarl Wibergvoid WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst)
574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
577608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg  InitFunctionPointers();
578608c3cfe77c165965ea04fcd0a2a71aad05a1d16kwiberg
579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* flag decoder init */
583470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->initflag |= 1;
584470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj);
586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj);
587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj);
588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
589470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* TS */
590470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj );
591470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
592470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5937796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
594470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACdec_obj.decimatorstr_obj);
595470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
596470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
597470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
598470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
599470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
600470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_UpdateBwEstimate1(...)
601470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
602470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function updates the estimate of the bandwidth.
603470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
606470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s).
607470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - packet_size       : size of the packet.
608470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rtp_seq_number    : the RTP number of the packet.
609470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - arr_ts            : the arrival time of the packet (from NetEq)
610470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            in samples.
611470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
612470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
613470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
614470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
615470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6160946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
6173f7f899a15c2685a8e45484f7b2c540771d28d90kwiberg@webrtc.org                                        const uint8_t* encoded,
618dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                        size_t packet_size,
619728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                        uint16_t rtp_seq_number,
620728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                        uint32_t arr_ts)
621470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
623470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
6240946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
625dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  const size_t kRequiredEncodedLenBytes = 10;
626470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
627470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
628470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
629470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
630470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Sanity check of packet length */
631dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  if (packet_size == 0) {
632470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if the packet length is null or less */
633470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
634470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
635470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (packet_size > (STREAM_MAXW16<<1)) {
636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if length of stream is too long */
637470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
638470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
641470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
642470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
643470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
644470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
645470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
646470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
647532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(packet_size, &streamdata);
648470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6490552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
650470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
651470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
652470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        &streamdata,
653470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        packet_size,
654470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        rtp_seq_number,
655470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        0,
656470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        arr_ts);
657470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
658470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
659470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err < 0)
660470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
661470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if something went wrong */
662470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = -err;
663470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
664470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
665470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
666470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
667470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
668470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
669470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
670470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
671470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_UpdateBwEstimate(...)
672470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
673470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function updates the estimate of the bandwidth.
674470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
675470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
676470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
677470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s).
678470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - packet_size       : size of the packet.
679470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rtp_seq_number    : the RTP number of the packet.
680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - send_ts           : Send Time Stamp from RTP header
681470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - arr_ts            : the arrival time of the packet (from NetEq)
682470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            in samples.
683470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  0 - Ok
685470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
686470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
687470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6880946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
6893f7f899a15c2685a8e45484f7b2c540771d28d90kwiberg@webrtc.org                                       const uint8_t* encoded,
690dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                       size_t packet_size,
691728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       uint16_t rtp_seq_number,
692728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       uint32_t send_ts,
693728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                       uint32_t arr_ts)
694470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
695470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
696470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
6970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
698dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  const size_t kRequiredEncodedLenBytes = 10;
699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
702470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Sanity check of packet length */
704dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  if (packet_size == 0) {
705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if the packet length is null  or less */
706470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
707470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
708532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  } else if (packet_size < kRequiredEncodedLenBytes) {
709532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    ISAC_inst->errorcode = ISAC_PACKET_TOO_SHORT;
710532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
711470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (packet_size > (STREAM_MAXW16<<1)) {
712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if length of stream is too long */
713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
717470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
718470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
719470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
720470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
721470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
723532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(packet_size, &streamdata);
724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
7250552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
726470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
728470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        &streamdata,
729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        packet_size,
730470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        rtp_seq_number,
731470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        send_ts,
732470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                        arr_ts);
733470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
734470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err < 0)
735470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
736470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if something went wrong */
737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = -err;
738470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
741470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
742470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
744470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
745470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
746470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Decode(...)
747470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function decodes a ISAC frame. Output speech length
749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * will be a multiple of 480 samples: 480 or 960 samples,
750470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * depending on the framesize (30 or 60 ms).
751470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
752470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
753470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
754470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded           : encoded ISAC frame(s)
755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - len               : bytes in encoded vector
756470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
760470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : >0 - number of samples in decoded vector
761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
762470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
763470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
765aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kastingint WebRtcIsacfix_Decode(ISACFIX_MainStruct* ISAC_main_inst,
766aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         const uint8_t* encoded,
767dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                         size_t len,
768aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         int16_t* decoded,
769aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                         int16_t* speechType)
770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
772470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* number of samples (480 or 960), output from decoder */
773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* that were actually used in the encoder/decoder (determined on the fly) */
774dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t number_of_samples;
775dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  int declen_int = 0;
776dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t declen;
777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
787470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Sanity check of packet length */
788dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  if (len == 0) {
789470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if the packet length is null  or less */
790470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
791470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (len > (STREAM_MAXW16<<1)) {
793470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* return error code if length of stream is too long */
794470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
795470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
796470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
797470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
798532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
799470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
8000552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
801470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
802470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* added for NetEq purposes (VAD/DTX related) */
803470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *speechType=1;
804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
805dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  declen_int = WebRtcIsacfix_DecodeImpl(decoded, &ISAC_inst->ISACdec_obj,
806dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                        &number_of_samples);
807dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  if (declen_int < 0) {
808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Some error inside the decoder */
809dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting    ISAC_inst->errorcode = -(int16_t)declen_int;
8100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    memset(decoded, 0, sizeof(int16_t) * MAX_FRAMESAMPLES);
811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
813dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  declen = (size_t)declen_int;
814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* error check */
816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
817b297c5a01f88219da26cffe433804963d1b70f0fpkasting  if (declen & 1) {
818b297c5a01f88219da26cffe433804963d1b70f0fpkasting    if (len != declen &&
819b297c5a01f88219da26cffe433804963d1b70f0fpkasting        len != declen +
820b297c5a01f88219da26cffe433804963d1b70f0fpkasting            ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) & 0xFF)) {
821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
8220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
826b297c5a01f88219da26cffe433804963d1b70f0fpkasting    if (len != declen &&
827b297c5a01f88219da26cffe433804963d1b70f0fpkasting        len != declen +
828b297c5a01f88219da26cffe433804963d1b70f0fpkasting            ((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
835dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  return (int)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
864dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingint WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct* ISAC_main_inst,
865dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                           const uint16_t* encoded,
866dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                           size_t len,
867dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                           int16_t* decoded,
868dce40cf804019a9898b6ab8d8262466b697c56e0Peter 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) */
873dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t number_of_samples;
874dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  int declen_int = 0;
875dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t declen;
8760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t dummy[FRAMESAMPLES/2];
877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
882470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if decoder initiated */
883470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 1) != 1) {
884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
888dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  if (len == 0) {
889532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    /* return error code if the packet length is null  or less */
890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
892532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  } else if (len > (STREAM_MAXW16<<1)) {
893532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    /* return error code if length of stream is too long */
894532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
895532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
896470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
897470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
898532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
9000552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* added for NetEq purposes (VAD/DTX related) */
903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *speechType=1;
904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
905dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  declen_int = WebRtcIsacfix_DecodeImpl(decoded, &ISAC_inst->ISACdec_obj,
906dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                        &number_of_samples);
907dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  if (declen_int < 0) {
908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Some error inside the decoder */
909dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting    ISAC_inst->errorcode = -(int16_t)declen_int;
9100946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    memset(decoded, 0, sizeof(int16_t) * FRAMESAMPLES);
911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
913dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  declen = (size_t)declen_int;
914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* error check */
916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
917b297c5a01f88219da26cffe433804963d1b70f0fpkasting  if (declen & 1) {
918b297c5a01f88219da26cffe433804963d1b70f0fpkasting    if (len != declen &&
919b297c5a01f88219da26cffe433804963d1b70f0fpkasting        len != declen +
920b297c5a01f88219da26cffe433804963d1b70f0fpkasting            ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) & 0xFF)) {
921470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
9220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
925470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
926b297c5a01f88219da26cffe433804963d1b70f0fpkasting    if (len != declen &&
927b297c5a01f88219da26cffe433804963d1b70f0fpkasting        len != declen +
928b297c5a01f88219da26cffe433804963d1b70f0fpkasting            ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >>1]) >> 8)) {
929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
9300946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org      memset(decoded, 0, sizeof(int16_t) * number_of_samples);
931470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return -1;
932470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
933470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
934470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
935470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  WebRtcIsacfix_SplitAndFilter2(decoded, decoded, dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
936470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
937470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (number_of_samples>FRAMESAMPLES) {
938470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcIsacfix_SplitAndFilter2(decoded + FRAMESAMPLES, decoded + FRAMESAMPLES/2,
939470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                  dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
942dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  return (int)(number_of_samples / 2);
943470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
9447796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
945470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
946470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
947470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
948470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecodePlcNb(...)
949470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
950470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
951470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output speech length  will be "240*noOfLostFrames" samples
952470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that is equevalent of "30*noOfLostFrames" millisecond.
953470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
9547796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
9557796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com *
956470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
957470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
958470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - noOfLostFrames    : Number of PLC frames (240 sample=30ms) to produce
959470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
960470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
961470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
963dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting * Return value             : Number of samples in decoded PLC vector
964470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
965470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
9667796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
967dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingsize_t WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct* ISAC_main_inst,
968dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                 int16_t* decoded,
969dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                 size_t noOfLostFrames )
970470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
971dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t no_of_samples, declen, k;
9720946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t outframeNB[FRAMESAMPLES];
9730946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t outframeWB[FRAMESAMPLES];
9740946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t dummy[FRAMESAMPLES/2];
975470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
976470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
977470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
979470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
980470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
981470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
982470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (noOfLostFrames > 2){
983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames = 2;
984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
985470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
986470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  k = 0;
987470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen = 0;
988470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  while( noOfLostFrames > 0 )
989470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
990728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting    WebRtcIsacfix_DecodePlcImpl(outframeWB, &ISAC_inst->ISACdec_obj,
991728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                &no_of_samples);
992470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
993470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    WebRtcIsacfix_SplitAndFilter2(outframeWB, &(outframeNB[k*240]), dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
994470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
995470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    declen += no_of_samples;
996470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames--;
997470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    k++;
998470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
999470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1000470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen>>=1;
1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1002470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<declen;k++) {
1003470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    decoded[k] = outframeNB[k];
1004470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1005470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1006470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return declen;
1007470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
10087796c02b4280139ea6e082b5012dd07f627267c1turajs@google.com#endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1011470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1012470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1013470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1014470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_DecodePlc(...)
1015470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
1017470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output speech length  will be "480*noOfLostFrames" samples
1018470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * that is equevalent of "30*noOfLostFrames" millisecond.
1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - noOfLostFrames    : Number of PLC frames (480sample = 30ms)
1023470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                                to produce
1024470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - decoded           : The decoded vector
1027470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1028dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting * Return value             : Number of samples in decoded PLC vector
1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1031dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kastingsize_t WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct* ISAC_main_inst,
1032dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                               int16_t* decoded,
1033dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                               size_t noOfLostFrames)
1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1036dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t no_of_samples, declen, k;
10370946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t outframe16[MAX_FRAMESAMPLES];
1038470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1041470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1042470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1043470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
1044470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (noOfLostFrames > 2) {
1045470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames = 2;
1046470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1047470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  k = 0;
1048470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  declen = 0;
1049470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  while( noOfLostFrames > 0 )
1050470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1051728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting    WebRtcIsacfix_DecodePlcImpl(&(outframe16[k*480]), &ISAC_inst->ISACdec_obj,
1052728d9037c016c01295177fa700fc7927f0bb80bbPeter Kasting                                &no_of_samples);
1053470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    declen += no_of_samples;
1054470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    noOfLostFrames--;
1055470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    k++;
1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1057470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1058470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  for (k=0;k<declen;k++) {
1059470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    decoded[k] = outframe16[k];
1060470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1061470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return declen;
1063470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1067470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_Control(...)
1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1069470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets the limit on the short-term average bit rate and the
1070470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * frame length. Should be used only in Instantaneous mode.
1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance.
1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rate              : limit on the short-term average bit rate,
1075470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            in bits/second (between 10000 and 32000)
1076470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - framesize         : number of milliseconds per frame (30 or 60)
1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : 0  - ok
1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            -1 - Error
1080470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1081470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
10820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
1083aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                              int16_t rate,
1084aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                              int framesize)
1085470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1086470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1087470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1088470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1089470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1090470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (ISAC_inst->CodingMode == 0)
1091470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1092470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* in adaptive mode */
1093470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1094470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1095470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1096470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1097470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1098470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (rate >= 10000 && rate <= 32000)
1099470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.BottleNeck = rate;
1100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else {
1101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1102470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1103470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1104470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1105470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1107470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (framesize  == 30 || framesize == 60)
1108aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * framesize);
1109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else {
1110470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1112470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1113470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1114470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11173258db26ed7cedd20e1e21aca70d8304c7cef218kwibergvoid WebRtcIsacfix_SetInitialBweBottleneck(ISACFIX_MainStruct* ISAC_main_inst,
11183258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg                                           int bottleneck_bits_per_second) {
11193258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg  ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
11203258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg  assert(bottleneck_bits_per_second >= 10000 &&
11213258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg         bottleneck_bits_per_second <= 32000);
11223258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg  inst->bwestimator_obj.sendBwAvg = ((uint32_t)bottleneck_bits_per_second) << 7;
11233258db26ed7cedd20e1e21aca70d8304c7cef218kwiberg}
1124470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_ControlBwe(...)
1127470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets the initial values of bottleneck and frame-size if
1129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * iSAC is used in channel-adaptive mode. Through this API, users can
1130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * enforce a frame-size for all values of bottleneck. Then iSAC will not
1131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * automatically change the frame-size.
1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  - ISAC_main_inst : ISAC instance.
1136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateBPS           : initial value of bottleneck in bits/second
1137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            10000 <= rateBPS <= 32000 is accepted
1138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            For default bottleneck set rateBPS = 0
1139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - frameSizeMs       : number of milliseconds per frame (30 or 60)
1140470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - enforceFrameSize  : 1 to enforce the given frame-size through out
1141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            the adaptation process, 0 to let iSAC change
1142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            the frame-size if required.
1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value    : 0  - ok
1145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *         -1 - Error
1146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11480946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
11490946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                 int16_t rateBPS,
1150aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting                                 int frameSizeMs,
11510946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                 int16_t enforceFrameSize)
1152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Typecast pointer to real structure */
1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* check if encoder initiated */
1158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((ISAC_inst->initflag & 2) != 2) {
1159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
1160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
1161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Check that we are in channel-adaptive mode, otherwise, return -1 */
1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (ISAC_inst->CodingMode != 0) {
1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
1167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */
1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* chosen frame size.                                                      */
1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0;
1172470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1173470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Set initial rate, if value between 10000 and 32000,                */
1174470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((rateBPS >= 10000) && (rateBPS <= 32000)) {
11760946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    ISAC_inst->bwestimator_obj.sendBwAvg = (((uint32_t)rateBPS) << 7);
1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else if (rateBPS != 0) {
1178470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Set initial framesize. If enforceFrameSize is set the frame size will not change */
1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
1184aba07ef6d92bf1ded7ad1af49b54a8e6652dfcbbPeter Kasting    ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * frameSizeMs);
1185470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
1186470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1192470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetDownLinkBwIndex(...)
1199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns index representing the Bandwidth estimate from
1201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * other side to this side.
1202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst: iSAC struct
1205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateIndex     : Bandwidth estimate to transmit to other side.
1208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12110946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
12120946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                         int16_t*     rateIndex)
1213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1217470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Call function to get Bandwidth Estimate */
1220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj);
1221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1222470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1223470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1224470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_UpdateUplinkBw(...)
1228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function takes an index representing the Bandwidth estimate from
1230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * this side to other side and updates BWE.
1231470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst: iSAC struct
1234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateIndex     : Bandwidth estimate from other side.
1235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12380946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
12390946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                     int16_t     rateIndex)
1240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
12410946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err = 0;
1242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1245470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1246470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1247470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* Call function to update BWE with received Bandwidth Estimate */
1248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex);
1249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err < 0) {
1250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->errorcode = -err;
1251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return (-1);
1252470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1253470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1257470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1258470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_ReadFrameLen(...)
1259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the length of the frame represented in the packet.
1261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded       : Encoded bitstream
1264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - frameLength   : Length of frame in packet (in samples)
1267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1268470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12701172988c794d15706b4c951dcbaa57b11221d225kwiberg@webrtc.orgint16_t WebRtcIsacfix_ReadFrameLen(const uint8_t* encoded,
1271dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                   size_t encoded_len_bytes,
1272dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                   size_t* frameLength)
1273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
12750946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
1276dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  const size_t kRequiredEncodedLenBytes = 10;
1277532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org
1278532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1279532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
1280532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  }
1281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1282532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
12840552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* decode frame length */
1287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
1288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err<0)  // error check
1289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
1290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1293470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1294470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1295470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1296470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_ReadBwIndex(...)
1297470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1298470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the index of the Bandwidth estimate from the bitstream.
1299470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1300470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1301470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - encoded       : Encoded bitstream
1302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1303470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - frameLength   : Length of frame in packet (in samples)
1305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - rateIndex     : Bandwidth estimate in bitstream
1306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1308470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13091172988c794d15706b4c951dcbaa57b11221d225kwiberg@webrtc.orgint16_t WebRtcIsacfix_ReadBwIndex(const uint8_t* encoded,
1310dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting                                  size_t encoded_len_bytes,
13110946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                  int16_t* rateIndex)
1312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1313470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  Bitstr_dec streamdata;
13140946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t err;
1315dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  const size_t kRequiredEncodedLenBytes = 10;
1316532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org
1317532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1318532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org    return -1;
1319532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  }
1320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1321532ed43e85356c6a775bebbf73ac5e9318d5bd66turaj@webrtc.org  InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13230552356fdac33cc803c3d3d9b65454c7bf236e42kwiberg@webrtc.org  read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* decode frame length, needed to get to the rateIndex in the bitstream */
1326dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting  size_t frameLength;
1327b297c5a01f88219da26cffe433804963d1b70f0fpkasting  err = WebRtcIsacfix_DecodeFrameLen(&streamdata, &frameLength);
1328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err<0)  // error check
1329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
1330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* decode BW estimation */
1332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex);
1333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err<0)  // error check
1334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
1335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetErrorCode(...)
1344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function can be used to check the error code of an iSAC instance. When
1346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * a function returns -1 a error code will be set for that instance. The
1347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * function below extract the code of the last error that occured in the
1348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * specified instance.
1349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : ISAC instance
1352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : Error code
1354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13560946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst)
1357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return ISAC_inst->errorcode;
1363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1365470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1366470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetUplinkBw(...)
1369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the inst quantized iSAC send bitrate
1371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : bitrate
1376470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1377470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13780946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint32_t WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst)
1379470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1380470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj);
1382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13830946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  return (int32_t) WebRtcIsacfix_GetUplinkBandwidth(bw);
1384470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_GetNewFrameLen(...)
1388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function return the next frame length (in samples) of iSAC.
1390470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1391470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             :  frame lenght in samples
1395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13970946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst)
1398470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return ISAC_inst->ISACenc_obj.new_framelength;
1401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1403470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_SetMaxPayloadSize(...)
1406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets a limit for the maximum payload size of iSAC. The same
1408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * value is used both for 30 and 60 msec packets.
1409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The absolute max will be valid until next time the function is called.
1410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
1411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1414470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - maxPayloadBytes   : maximum size of the payload in bytes
1415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            valid values are between 100 and 400 bytes
1416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1418470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : 0 if sucessful
1419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                           -1 if error happens
1420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
14220946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
14230946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                        int16_t maxPayloadBytes)
1424470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
1426470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1428470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if((maxPayloadBytes < 100) || (maxPayloadBytes > 400))
1431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* maxPayloadBytes is out of valid range */
1433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1435470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
1436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Set new absolute max, which will not change unless this function
1438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       is called again with a new value */
1439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes;
1440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1441470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Set new maximum values for 30 and 60 msec packets */
1442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) {
1443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes;
1444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes;
1446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) {
1449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes;
1450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1);
1452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_SetMaxRate(...)
1460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function sets the maximum rate which the codec may not exceed for a
1462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * singel packet. The maximum rate is set in bits per second.
1463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
1464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * per 30 msec).
1465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * It is possible to set a maximum rate between 32000 and 53400 bits per second.
1466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * The rate limit is valid until next time the function is called.
1468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * NOTE! Packet size will never go above the value set if calling
1470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
1471470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Input:
1473470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - ISAC_main_inst    : iSAC instance
1474470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - maxRateInBytes    : maximum rate in bits per second,
1475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                            valid values are 32000 to 53400 bits
1476470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1477470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Return value             : 0 if sucessful
1478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *                           -1 if error happens
1479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
14810946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgint16_t WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
14820946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                                 int32_t maxRate)
1483470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISACFIX_SubStruct *ISAC_inst;
14850946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org  int16_t maxRateInBytes;
1486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1487470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  /* typecast pointer to real structure */
1488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if((maxRate < 32000) || (maxRate > 53400))
1491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* maxRate is out of valid range */
1493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return -1;
1494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  else
1496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  {
1497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Calculate maximum number of bytes per 30 msec packets for the given
1498470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       maximum rate. Multiply with 30/1000 to get number of bits per 30 msec,
1499470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       divide by 8 to get number of bytes per 30 msec:
1500470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       maxRateInBytes = floor((maxRate * 30/1000) / 8); */
15010946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org    maxRateInBytes = (int16_t)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) );
1502470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1503470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */
1504470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes;
1505470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1506470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* For 30 msec packets: if the new limit is below the maximum
1507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       payload size, set a new limit */
1508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1509470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes;
1510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    /* For 60 msec packets: if the new limit (times 2) is below the
1515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com       maximum payload size, set a new limit */
1516470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1);
1518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    } else {
1519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
1521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
1522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return 0;
1524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
1525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/****************************************************************************
1529470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * WebRtcIsacfix_version(...)
1530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * This function returns the version number.
1532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Output:
1534470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *      - version  : Pointer to character string
1535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
1536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
1537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comvoid WebRtcIsacfix_version(char *version)
1539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com{
1540470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  strcpy(version, "3.6.0");
1541470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
15422224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg
15432224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wibergvoid WebRtcIsacfix_GetBandwidthInfo(ISACFIX_MainStruct* ISAC_main_inst,
15442224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg                                    IsacBandwidthInfo* bwinfo) {
15452224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
15462224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  assert(inst->initflag & 1);  // Decoder initialized.
15472224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  WebRtcIsacfixBw_GetBandwidthInfo(&inst->bwestimator_obj, bwinfo);
15482224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg}
15492224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg
15502224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wibergvoid WebRtcIsacfix_SetBandwidthInfo(ISACFIX_MainStruct* ISAC_main_inst,
15512224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg                                    const IsacBandwidthInfo* bwinfo) {
15522224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
15532224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  assert(inst->initflag & 2);  // Encoder initialized.
15542224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg  WebRtcIsacfixBw_SetBandwidthInfo(&inst->bwestimator_obj, bwinfo);
15552224294c52fc0bb95eedb8187a62bedf1b5eb853Karl Wiberg}
1556