• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /*
12  * isacfix.c
13  *
14  * This C file contains the functions for the ISAC API
15  *
16  */
17 
18 #include "webrtc/modules/audio_coding/codecs/isac/fix/include/isacfix.h"
19 
20 #include <assert.h>
21 #include <stdlib.h>
22 
23 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
24 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"
25 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
26 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
27 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
28 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h"
29 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
30 
31 // Declare function pointers.
32 FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
33 Spec2Time WebRtcIsacfix_Spec2Time;
34 Time2Spec WebRtcIsacfix_Time2Spec;
35 MatrixProduct1 WebRtcIsacfix_MatrixProduct1;
36 MatrixProduct2 WebRtcIsacfix_MatrixProduct2;
37 
38 /* This method assumes that |stream_size_bytes| is in valid range,
39  * i.e. >= 0 && <=  STREAM_MAXW16_60MS
40  */
InitializeDecoderBitstream(size_t stream_size_bytes,Bitstr_dec * bitstream)41 static void InitializeDecoderBitstream(size_t stream_size_bytes,
42                                        Bitstr_dec* bitstream) {
43   bitstream->W_upper = 0xFFFFFFFF;
44   bitstream->streamval = 0;
45   bitstream->stream_index = 0;
46   bitstream->full = 1;
47   bitstream->stream_size = (stream_size_bytes + 1) >> 1;
48   memset(bitstream->stream, 0, sizeof(bitstream->stream));
49 }
50 
51 /**************************************************************************
52  * WebRtcIsacfix_AssignSize(...)
53  *
54  * Functions used when malloc is not allowed
55  * Returns number of bytes needed to allocate for iSAC struct.
56  *
57  */
58 
WebRtcIsacfix_AssignSize(int * sizeinbytes)59 int16_t WebRtcIsacfix_AssignSize(int *sizeinbytes) {
60   *sizeinbytes=sizeof(ISACFIX_SubStruct)*2/sizeof(int16_t);
61   return(0);
62 }
63 
64 /***************************************************************************
65  * WebRtcIsacfix_Assign(...)
66  *
67  * Functions used when malloc is not allowed
68  * Place struct at given address
69  *
70  * If successful, Return 0, else Return -1
71  */
72 
WebRtcIsacfix_Assign(ISACFIX_MainStruct ** inst,void * ISACFIX_inst_Addr)73 int16_t WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst, void *ISACFIX_inst_Addr) {
74   if (ISACFIX_inst_Addr!=NULL) {
75     ISACFIX_SubStruct* self = ISACFIX_inst_Addr;
76     *inst = (ISACFIX_MainStruct*)self;
77     self->errorcode = 0;
78     self->initflag = 0;
79     self->ISACenc_obj.SaveEnc_ptr = NULL;
80     WebRtcIsacfix_InitBandwidthEstimator(&self->bwestimator_obj);
81     return(0);
82   } else {
83     return(-1);
84   }
85 }
86 
87 
88 #ifndef ISACFIX_NO_DYNAMIC_MEM
89 
90 /****************************************************************************
91  * WebRtcIsacfix_Create(...)
92  *
93  * This function creates a ISAC instance, which will contain the state
94  * information for one coding/decoding channel.
95  *
96  * Input:
97  *      - *ISAC_main_inst   : a pointer to the coder instance.
98  *
99  * Return value             :  0 - Ok
100  *                            -1 - Error
101  */
102 
WebRtcIsacfix_Create(ISACFIX_MainStruct ** ISAC_main_inst)103 int16_t WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst)
104 {
105   ISACFIX_SubStruct *tempo;
106   tempo = malloc(1 * sizeof(ISACFIX_SubStruct));
107   *ISAC_main_inst = (ISACFIX_MainStruct *)tempo;
108   if (*ISAC_main_inst!=NULL) {
109     (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0;
110     (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0;
111     (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL;
112     WebRtcSpl_Init();
113     WebRtcIsacfix_InitBandwidthEstimator(&tempo->bwestimator_obj);
114     return(0);
115   } else {
116     return(-1);
117   }
118 }
119 
120 
121 /****************************************************************************
122  * WebRtcIsacfix_CreateInternal(...)
123  *
124  * This function creates the memory that is used to store data in the encoder
125  *
126  * Input:
127  *      - *ISAC_main_inst   : a pointer to the coder instance.
128  *
129  * Return value             :  0 - Ok
130  *                            -1 - Error
131  */
132 
WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct * ISAC_main_inst)133 int16_t WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst)
134 {
135   ISACFIX_SubStruct *ISAC_inst;
136 
137   /* typecast pointer to real structure */
138   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
139 
140   /* Allocate memory for storing encoder data */
141   ISAC_inst->ISACenc_obj.SaveEnc_ptr = malloc(1 * sizeof(IsacSaveEncoderData));
142 
143   if (ISAC_inst->ISACenc_obj.SaveEnc_ptr!=NULL) {
144     return(0);
145   } else {
146     return(-1);
147   }
148 }
149 
150 
151 #endif
152 
153 
154 
155 /****************************************************************************
156  * WebRtcIsacfix_Free(...)
157  *
158  * This function frees the ISAC instance created at the beginning.
159  *
160  * Input:
161  *      - ISAC_main_inst    : a ISAC instance.
162  *
163  * Return value             :  0 - Ok
164  *                            -1 - Error
165  */
166 
WebRtcIsacfix_Free(ISACFIX_MainStruct * ISAC_main_inst)167 int16_t WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst)
168 {
169   free(ISAC_main_inst);
170   return(0);
171 }
172 
173 /****************************************************************************
174  * WebRtcIsacfix_FreeInternal(...)
175  *
176  * This function frees the internal memory for storing encoder data.
177  *
178  * Input:
179  *       - ISAC_main_inst    : a ISAC instance.
180  *
181  * Return value              :  0 - Ok
182  *                             -1 - Error
183  */
184 
WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct * ISAC_main_inst)185 int16_t WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst)
186 {
187   ISACFIX_SubStruct *ISAC_inst;
188 
189   /* typecast pointer to real structure */
190   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
191 
192   /* Release memory */
193   free(ISAC_inst->ISACenc_obj.SaveEnc_ptr);
194 
195   return(0);
196 }
197 
198 /****************************************************************************
199  * WebRtcIsacfix_InitNeon(...)
200  *
201  * This function initializes function pointers for ARM Neon platform.
202  */
203 
204 #if defined(WEBRTC_DETECT_NEON) || defined(WEBRTC_HAS_NEON)
WebRtcIsacfix_InitNeon(void)205 static void WebRtcIsacfix_InitNeon(void) {
206   WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon;
207   WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon;
208   WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeNeon;
209   WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecNeon;
210   WebRtcIsacfix_AllpassFilter2FixDec16 =
211       WebRtcIsacfix_AllpassFilter2FixDec16Neon;
212   WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1Neon;
213   WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2Neon;
214 }
215 #endif
216 
217 /****************************************************************************
218  * WebRtcIsacfix_InitMIPS(...)
219  *
220  * This function initializes function pointers for MIPS platform.
221  */
222 
223 #if defined(MIPS32_LE)
WebRtcIsacfix_InitMIPS(void)224 static void WebRtcIsacfix_InitMIPS(void) {
225   WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrMIPS;
226   WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopMIPS;
227   WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeMIPS;
228   WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecMIPS;
229   WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1MIPS;
230   WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2MIPS;
231 #if defined(MIPS_DSP_R1_LE)
232   WebRtcIsacfix_AllpassFilter2FixDec16 =
233       WebRtcIsacfix_AllpassFilter2FixDec16MIPS;
234   WebRtcIsacfix_HighpassFilterFixDec32 =
235       WebRtcIsacfix_HighpassFilterFixDec32MIPS;
236 #endif
237 #if defined(MIPS_DSP_R2_LE)
238   WebRtcIsacfix_CalculateResidualEnergy =
239       WebRtcIsacfix_CalculateResidualEnergyMIPS;
240 #endif
241 }
242 #endif
243 
InitFunctionPointers(void)244 static void InitFunctionPointers(void) {
245   WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
246   WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
247   WebRtcIsacfix_CalculateResidualEnergy =
248       WebRtcIsacfix_CalculateResidualEnergyC;
249   WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
250   WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
251   WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
252   WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
253   WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
254   WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
255 
256 #ifdef WEBRTC_DETECT_NEON
257   if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
258     WebRtcIsacfix_InitNeon();
259   }
260 #elif defined(WEBRTC_HAS_NEON)
261   WebRtcIsacfix_InitNeon();
262 #endif
263 
264 #if defined(MIPS32_LE)
265   WebRtcIsacfix_InitMIPS();
266 #endif
267 }
268 
269 /****************************************************************************
270  * WebRtcIsacfix_EncoderInit(...)
271  *
272  * This function initializes a ISAC instance prior to the encoder calls.
273  *
274  * Input:
275  *      - ISAC_main_inst    : ISAC instance.
276  *      - CodingMode        : 0 -> Bit rate and frame length are automatically
277  *                                 adjusted to available bandwidth on
278  *                                 transmission channel.
279  *                            1 -> User sets a frame length and a target bit
280  *                                 rate which is taken as the maximum short-term
281  *                                 average bit rate.
282  *
283  * Return value             :  0 - Ok
284  *                            -1 - Error
285  */
286 
WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct * ISAC_main_inst,int16_t CodingMode)287 int16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
288                                   int16_t  CodingMode)
289 {
290   int k;
291   int16_t statusInit;
292   ISACFIX_SubStruct *ISAC_inst;
293 
294   statusInit = 0;
295   /* typecast pointer to rela structure */
296   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
297 
298   /* flag encoder init */
299   ISAC_inst->initflag |= 2;
300 
301   if (CodingMode == 0)
302     /* Adaptive mode */
303     ISAC_inst->ISACenc_obj.new_framelength  = INITIAL_FRAMESAMPLES;
304   else if (CodingMode == 1)
305     /* Instantaneous mode */
306     ISAC_inst->ISACenc_obj.new_framelength = 480;    /* default for I-mode */
307   else {
308     ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE;
309     statusInit = -1;
310   }
311 
312   ISAC_inst->CodingMode = CodingMode;
313 
314   WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj);
315   WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj);
316   WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj);
317   WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj);
318 
319   WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj);
320 
321 
322   ISAC_inst->ISACenc_obj.buffer_index   = 0;
323   ISAC_inst->ISACenc_obj.frame_nb    = 0;
324   ISAC_inst->ISACenc_obj.BottleNeck      = 32000; /* default for I-mode */
325   ISAC_inst->ISACenc_obj.MaxDelay    = 10;    /* default for I-mode */
326   ISAC_inst->ISACenc_obj.current_framesamples = 0;
327   ISAC_inst->ISACenc_obj.s2nr     = 0;
328   ISAC_inst->ISACenc_obj.MaxBits    = 0;
329   ISAC_inst->ISACenc_obj.bitstr_seed   = 4447;
330   ISAC_inst->ISACenc_obj.payloadLimitBytes30  = STREAM_MAXW16_30MS << 1;
331   ISAC_inst->ISACenc_obj.payloadLimitBytes60  = STREAM_MAXW16_60MS << 1;
332   ISAC_inst->ISACenc_obj.maxPayloadBytes      = STREAM_MAXW16_60MS << 1;
333   ISAC_inst->ISACenc_obj.maxRateInBytes       = STREAM_MAXW16_30MS << 1;
334   ISAC_inst->ISACenc_obj.enforceFrameSize     = 0;
335 
336   /* Init the bistream data area to zero */
337   for (k=0; k<STREAM_MAXW16_60MS; k++){
338     ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0;
339   }
340 
341 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
342   WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj);
343 #endif
344 
345   InitFunctionPointers();
346 
347   return statusInit;
348 }
349 
350 /* Read the given number of bytes of big-endian 16-bit integers from |src| and
351    write them to |dest| in host endian. If |nbytes| is odd, the number of
352    output elements is rounded up, and the least significant byte of the last
353    element is set to 0. */
read_be16(const uint8_t * src,size_t nbytes,uint16_t * dest)354 static void read_be16(const uint8_t* src, size_t nbytes, uint16_t* dest) {
355   size_t i;
356   for (i = 0; i < nbytes / 2; ++i)
357     dest[i] = src[2 * i] << 8 | src[2 * i + 1];
358   if (nbytes % 2 == 1)
359     dest[nbytes / 2] = src[nbytes - 1] << 8;
360 }
361 
362 /* Read the given number of bytes of host-endian 16-bit integers from |src| and
363    write them to |dest| in big endian. If |nbytes| is odd, the number of source
364    elements is rounded up (but only the most significant byte of the last
365    element is used), and the number of output bytes written will be
366    nbytes + 1. */
write_be16(const uint16_t * src,size_t nbytes,uint8_t * dest)367 static void write_be16(const uint16_t* src, size_t nbytes, uint8_t* dest) {
368   size_t i;
369   for (i = 0; i < nbytes / 2; ++i) {
370     dest[2 * i] = src[i] >> 8;
371     dest[2 * i + 1] = src[i];
372   }
373   if (nbytes % 2 == 1) {
374     dest[nbytes - 1] = src[nbytes / 2] >> 8;
375     dest[nbytes] = 0;
376   }
377 }
378 
379 /****************************************************************************
380  * WebRtcIsacfix_Encode(...)
381  *
382  * This function encodes 10ms frame(s) and inserts it into a package.
383  * Input speech length has to be 160 samples (10ms). The encoder buffers those
384  * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
385  * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
386  *
387  * Input:
388  *      - ISAC_main_inst    : ISAC instance.
389  *      - speechIn          : input speech vector.
390  *
391  * Output:
392  *      - encoded           : the encoded data vector
393  *
394  * Return value:
395  *                          : >0 - Length (in bytes) of coded data
396  *                          :  0 - The buffer didn't reach the chosen framesize
397  *                            so it keeps buffering speech samples.
398  *                          : -1 - Error
399  */
400 
WebRtcIsacfix_Encode(ISACFIX_MainStruct * ISAC_main_inst,const int16_t * speechIn,uint8_t * encoded)401 int WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
402                          const int16_t    *speechIn,
403                          uint8_t* encoded)
404 {
405   ISACFIX_SubStruct *ISAC_inst;
406   int stream_len;
407 
408   /* typecast pointer to rela structure */
409   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
410 
411 
412   /* check if encoder initiated */
413   if ((ISAC_inst->initflag & 2) != 2) {
414     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
415     return (-1);
416   }
417 
418   stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechIn,
419                                         &ISAC_inst->ISACenc_obj,
420                                         &ISAC_inst->bwestimator_obj,
421                                         ISAC_inst->CodingMode);
422   if (stream_len<0) {
423     ISAC_inst->errorcode = -(int16_t)stream_len;
424     return -1;
425   }
426 
427   write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, (size_t)stream_len,
428              encoded);
429   return stream_len;
430 
431 }
432 
433 
434 
435 
436 /****************************************************************************
437  * WebRtcIsacfix_EncodeNb(...)
438  *
439  * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
440  * it into a package. Input speech length has to be 80 samples (10ms). The encoder
441  * interpolates into wide-band (16 kHz sampling) buffers those
442  * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
443  * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
444  *
445  * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
446  *
447  * Input:
448  *      - ISAC_main_inst    : ISAC instance.
449  *      - speechIn          : input speech vector.
450  *
451  * Output:
452  *      - encoded           : the encoded data vector
453  *
454  * Return value:
455  *                          : >0 - Length (in bytes) of coded data
456  *                          :  0 - The buffer didn't reach the chosen framesize
457  *                            so it keeps buffering speech samples.
458  *                          : -1 - Error
459  */
460 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct * ISAC_main_inst,const int16_t * speechIn,int16_t * encoded)461 int16_t WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
462                                const int16_t    *speechIn,
463                                int16_t          *encoded)
464 {
465   ISACFIX_SubStruct *ISAC_inst;
466   int16_t stream_len;
467   int16_t speechInWB[FRAMESAMPLES_10ms];
468   int16_t Vector_Word16_1[FRAMESAMPLES_10ms/2];
469   int16_t Vector_Word16_2[FRAMESAMPLES_10ms/2];
470 
471   int k;
472 
473 
474   /* typecast pointer to rela structure */
475   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
476 
477 
478   /* check if encoder initiated */
479   if ((ISAC_inst->initflag & 2) != 2) {
480     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
481     return (-1);
482   }
483 
484 
485   /* Oversample to WB */
486 
487   /* Form polyphase signals, and compensate for DC offset */
488   for (k=0;k<FRAMESAMPLES_10ms/2;k++) {
489     Vector_Word16_1[k] = speechIn[k] + 1;
490     Vector_Word16_2[k] = speechIn[k];
491   }
492   WebRtcIsacfix_FilterAndCombine2(Vector_Word16_1, Vector_Word16_2, speechInWB, &ISAC_inst->ISACenc_obj.interpolatorstr_obj, FRAMESAMPLES_10ms);
493 
494 
495   /* Encode WB signal */
496   stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechInWB,
497                                         &ISAC_inst->ISACenc_obj,
498                                         &ISAC_inst->bwestimator_obj,
499                                         ISAC_inst->CodingMode);
500   if (stream_len<0) {
501     ISAC_inst->errorcode = - stream_len;
502     return -1;
503   }
504 
505   write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream,
506              stream_len,
507              (uint8_t*)encoded);
508   return stream_len;
509 }
510 #endif  /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
511 
512 
513 /****************************************************************************
514  * WebRtcIsacfix_GetNewBitStream(...)
515  *
516  * This function returns encoded data, with the recieved bwe-index in the
517  * stream. It should always return a complete packet, i.e. only called once
518  * even for 60 msec frames
519  *
520  * Input:
521  *      - ISAC_main_inst    : ISAC instance.
522  *      - bweIndex          : index of bandwidth estimate to put in new bitstream
523  *
524  * Output:
525  *      - encoded           : the encoded data vector
526  *
527  * Return value:
528  *                          : >0 - Length (in bytes) of coded data
529  *                          : -1 - Error
530  */
531 
WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct * ISAC_main_inst,int16_t bweIndex,float scale,uint8_t * encoded)532 int16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
533                                       int16_t      bweIndex,
534                                       float              scale,
535                                       uint8_t* encoded)
536 {
537   ISACFIX_SubStruct *ISAC_inst;
538   int16_t stream_len;
539 
540   /* typecast pointer to rela structure */
541   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
542 
543 
544   /* check if encoder initiated */
545   if ((ISAC_inst->initflag & 2) != 2) {
546     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
547     return (-1);
548   }
549 
550   stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj,
551                                               bweIndex,
552                                               scale);
553   if (stream_len<0) {
554     ISAC_inst->errorcode = - stream_len;
555     return -1;
556   }
557 
558   write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len, encoded);
559   return stream_len;
560 }
561 
562 
563 
564 /****************************************************************************
565  * WebRtcIsacfix_DecoderInit(...)
566  *
567  * This function initializes a ISAC instance prior to the decoder calls.
568  *
569  * Input:
570  *      - ISAC_main_inst    : ISAC instance.
571  */
572 
WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct * ISAC_main_inst)573 void WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst)
574 {
575   ISACFIX_SubStruct *ISAC_inst;
576 
577   InitFunctionPointers();
578 
579   /* typecast pointer to real structure */
580   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
581 
582   /* flag decoder init */
583   ISAC_inst->initflag |= 1;
584 
585   WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj);
586   WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj);
587   WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj);
588 
589   /* TS */
590   WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj );
591 
592 
593 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
594   WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACdec_obj.decimatorstr_obj);
595 #endif
596 }
597 
598 
599 /****************************************************************************
600  * WebRtcIsacfix_UpdateBwEstimate1(...)
601  *
602  * This function updates the estimate of the bandwidth.
603  *
604  * Input:
605  *      - ISAC_main_inst    : ISAC instance.
606  *      - encoded           : encoded ISAC frame(s).
607  *      - packet_size       : size of the packet.
608  *      - rtp_seq_number    : the RTP number of the packet.
609  *      - arr_ts            : the arrival time of the packet (from NetEq)
610  *                            in samples.
611  *
612  * Return value             :  0 - Ok
613  *                            -1 - Error
614  */
615 
WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct * ISAC_main_inst,const uint8_t * encoded,size_t packet_size,uint16_t rtp_seq_number,uint32_t arr_ts)616 int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
617                                         const uint8_t* encoded,
618                                         size_t packet_size,
619                                         uint16_t rtp_seq_number,
620                                         uint32_t arr_ts)
621 {
622   ISACFIX_SubStruct *ISAC_inst;
623   Bitstr_dec streamdata;
624   int16_t err;
625   const size_t kRequiredEncodedLenBytes = 10;
626 
627   /* typecast pointer to real structure */
628   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
629 
630   /* Sanity check of packet length */
631   if (packet_size == 0) {
632     /* return error code if the packet length is null or less */
633     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
634     return -1;
635   } else if (packet_size > (STREAM_MAXW16<<1)) {
636     /* return error code if length of stream is too long */
637     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
638     return -1;
639   }
640 
641   /* check if decoder initiated */
642   if ((ISAC_inst->initflag & 1) != 1) {
643     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
644     return (-1);
645   }
646 
647   InitializeDecoderBitstream(packet_size, &streamdata);
648 
649   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
650 
651   err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
652                                         &streamdata,
653                                         packet_size,
654                                         rtp_seq_number,
655                                         0,
656                                         arr_ts);
657 
658 
659   if (err < 0)
660   {
661     /* return error code if something went wrong */
662     ISAC_inst->errorcode = -err;
663     return -1;
664   }
665 
666 
667   return 0;
668 }
669 
670 /****************************************************************************
671  * WebRtcIsacfix_UpdateBwEstimate(...)
672  *
673  * This function updates the estimate of the bandwidth.
674  *
675  * Input:
676  *      - ISAC_main_inst    : ISAC instance.
677  *      - encoded           : encoded ISAC frame(s).
678  *      - packet_size       : size of the packet.
679  *      - rtp_seq_number    : the RTP number of the packet.
680  *      - send_ts           : Send Time Stamp from RTP header
681  *      - arr_ts            : the arrival time of the packet (from NetEq)
682  *                            in samples.
683  *
684  * Return value             :  0 - Ok
685  *                            -1 - Error
686  */
687 
WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct * ISAC_main_inst,const uint8_t * encoded,size_t packet_size,uint16_t rtp_seq_number,uint32_t send_ts,uint32_t arr_ts)688 int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
689                                        const uint8_t* encoded,
690                                        size_t packet_size,
691                                        uint16_t rtp_seq_number,
692                                        uint32_t send_ts,
693                                        uint32_t arr_ts)
694 {
695   ISACFIX_SubStruct *ISAC_inst;
696   Bitstr_dec streamdata;
697   int16_t err;
698   const size_t kRequiredEncodedLenBytes = 10;
699 
700   /* typecast pointer to real structure */
701   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
702 
703   /* Sanity check of packet length */
704   if (packet_size == 0) {
705     /* return error code if the packet length is null  or less */
706     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
707     return -1;
708   } else if (packet_size < kRequiredEncodedLenBytes) {
709     ISAC_inst->errorcode = ISAC_PACKET_TOO_SHORT;
710     return -1;
711   } else if (packet_size > (STREAM_MAXW16<<1)) {
712     /* return error code if length of stream is too long */
713     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
714     return -1;
715   }
716 
717   /* check if decoder initiated */
718   if ((ISAC_inst->initflag & 1) != 1) {
719     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
720     return (-1);
721   }
722 
723   InitializeDecoderBitstream(packet_size, &streamdata);
724 
725   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
726 
727   err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
728                                         &streamdata,
729                                         packet_size,
730                                         rtp_seq_number,
731                                         send_ts,
732                                         arr_ts);
733 
734   if (err < 0)
735   {
736     /* return error code if something went wrong */
737     ISAC_inst->errorcode = -err;
738     return -1;
739   }
740 
741 
742   return 0;
743 }
744 
745 /****************************************************************************
746  * WebRtcIsacfix_Decode(...)
747  *
748  * This function decodes a ISAC frame. Output speech length
749  * will be a multiple of 480 samples: 480 or 960 samples,
750  * depending on the framesize (30 or 60 ms).
751  *
752  * Input:
753  *      - ISAC_main_inst    : ISAC instance.
754  *      - encoded           : encoded ISAC frame(s)
755  *      - len               : bytes in encoded vector
756  *
757  * Output:
758  *      - decoded           : The decoded vector
759  *
760  * Return value             : >0 - number of samples in decoded vector
761  *                            -1 - Error
762  */
763 
764 
WebRtcIsacfix_Decode(ISACFIX_MainStruct * ISAC_main_inst,const uint8_t * encoded,size_t len,int16_t * decoded,int16_t * speechType)765 int WebRtcIsacfix_Decode(ISACFIX_MainStruct* ISAC_main_inst,
766                          const uint8_t* encoded,
767                          size_t len,
768                          int16_t* decoded,
769                          int16_t* speechType)
770 {
771   ISACFIX_SubStruct *ISAC_inst;
772   /* number of samples (480 or 960), output from decoder */
773   /* that were actually used in the encoder/decoder (determined on the fly) */
774   size_t number_of_samples;
775   int declen_int = 0;
776   size_t declen;
777 
778   /* typecast pointer to real structure */
779   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
780 
781   /* check if decoder initiated */
782   if ((ISAC_inst->initflag & 1) != 1) {
783     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
784     return (-1);
785   }
786 
787   /* Sanity check of packet length */
788   if (len == 0) {
789     /* return error code if the packet length is null  or less */
790     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
791     return -1;
792   } else if (len > (STREAM_MAXW16<<1)) {
793     /* return error code if length of stream is too long */
794     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
795     return -1;
796   }
797 
798   InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
799 
800   read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
801 
802   /* added for NetEq purposes (VAD/DTX related) */
803   *speechType=1;
804 
805   declen_int = WebRtcIsacfix_DecodeImpl(decoded, &ISAC_inst->ISACdec_obj,
806                                         &number_of_samples);
807   if (declen_int < 0) {
808     /* Some error inside the decoder */
809     ISAC_inst->errorcode = -(int16_t)declen_int;
810     memset(decoded, 0, sizeof(int16_t) * MAX_FRAMESAMPLES);
811     return -1;
812   }
813   declen = (size_t)declen_int;
814 
815   /* error check */
816 
817   if (declen & 1) {
818     if (len != declen &&
819         len != declen +
820             ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) & 0xFF)) {
821       ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
822       memset(decoded, 0, sizeof(int16_t) * number_of_samples);
823       return -1;
824     }
825   } else {
826     if (len != declen &&
827         len != declen +
828             ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) >> 8)) {
829       ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
830       memset(decoded, 0, sizeof(int16_t) * number_of_samples);
831       return -1;
832     }
833   }
834 
835   return (int)number_of_samples;
836 }
837 
838 
839 
840 
841 
842 /****************************************************************************
843  * WebRtcIsacfix_DecodeNb(...)
844  *
845  * This function decodes a ISAC frame in narrow-band (8 kHz sampling).
846  * Output speech length will be a multiple of 240 samples: 240 or 480 samples,
847  * depending on the framesize (30 or 60 ms).
848  *
849  * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
850  *
851  * Input:
852  *      - ISAC_main_inst    : ISAC instance.
853  *      - encoded           : encoded ISAC frame(s)
854  *      - len               : bytes in encoded vector
855  *
856  * Output:
857  *      - decoded           : The decoded vector
858  *
859  * Return value             : >0 - number of samples in decoded vector
860  *                            -1 - Error
861  */
862 
863 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct * ISAC_main_inst,const uint16_t * encoded,size_t len,int16_t * decoded,int16_t * speechType)864 int WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct* ISAC_main_inst,
865                            const uint16_t* encoded,
866                            size_t len,
867                            int16_t* decoded,
868                            int16_t* speechType)
869 {
870   ISACFIX_SubStruct *ISAC_inst;
871   /* twice the number of samples (480 or 960), output from decoder */
872   /* that were actually used in the encoder/decoder (determined on the fly) */
873   size_t number_of_samples;
874   int declen_int = 0;
875   size_t declen;
876   int16_t dummy[FRAMESAMPLES/2];
877 
878 
879   /* typecast pointer to real structure */
880   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
881 
882   /* check if decoder initiated */
883   if ((ISAC_inst->initflag & 1) != 1) {
884     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
885     return (-1);
886   }
887 
888   if (len == 0) {
889     /* return error code if the packet length is null  or less */
890     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
891     return -1;
892   } else if (len > (STREAM_MAXW16<<1)) {
893     /* return error code if length of stream is too long */
894     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
895     return -1;
896   }
897 
898   InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
899 
900   read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
901 
902   /* added for NetEq purposes (VAD/DTX related) */
903   *speechType=1;
904 
905   declen_int = WebRtcIsacfix_DecodeImpl(decoded, &ISAC_inst->ISACdec_obj,
906                                         &number_of_samples);
907   if (declen_int < 0) {
908     /* Some error inside the decoder */
909     ISAC_inst->errorcode = -(int16_t)declen_int;
910     memset(decoded, 0, sizeof(int16_t) * FRAMESAMPLES);
911     return -1;
912   }
913   declen = (size_t)declen_int;
914 
915   /* error check */
916 
917   if (declen & 1) {
918     if (len != declen &&
919         len != declen +
920             ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) & 0xFF)) {
921       ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
922       memset(decoded, 0, sizeof(int16_t) * number_of_samples);
923       return -1;
924     }
925   } else {
926     if (len != declen &&
927         len != declen +
928             ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >>1]) >> 8)) {
929       ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
930       memset(decoded, 0, sizeof(int16_t) * number_of_samples);
931       return -1;
932     }
933   }
934 
935   WebRtcIsacfix_SplitAndFilter2(decoded, decoded, dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
936 
937   if (number_of_samples>FRAMESAMPLES) {
938     WebRtcIsacfix_SplitAndFilter2(decoded + FRAMESAMPLES, decoded + FRAMESAMPLES/2,
939                                   dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
940   }
941 
942   return (int)(number_of_samples / 2);
943 }
944 #endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
945 
946 
947 /****************************************************************************
948  * WebRtcIsacfix_DecodePlcNb(...)
949  *
950  * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
951  * Output speech length  will be "240*noOfLostFrames" samples
952  * that is equevalent of "30*noOfLostFrames" millisecond.
953  *
954  * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
955  *
956  * Input:
957  *      - ISAC_main_inst    : ISAC instance.
958  *      - noOfLostFrames    : Number of PLC frames (240 sample=30ms) to produce
959  *
960  * Output:
961  *      - decoded           : The decoded vector
962  *
963  * Return value             : Number of samples in decoded PLC vector
964  */
965 
966 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct * ISAC_main_inst,int16_t * decoded,size_t noOfLostFrames)967 size_t WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct* ISAC_main_inst,
968                                  int16_t* decoded,
969                                  size_t noOfLostFrames )
970 {
971   size_t no_of_samples, declen, k;
972   int16_t outframeNB[FRAMESAMPLES];
973   int16_t outframeWB[FRAMESAMPLES];
974   int16_t dummy[FRAMESAMPLES/2];
975 
976 
977   ISACFIX_SubStruct *ISAC_inst;
978   /* typecast pointer to real structure */
979   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
980 
981   /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
982   if (noOfLostFrames > 2){
983     noOfLostFrames = 2;
984   }
985 
986   k = 0;
987   declen = 0;
988   while( noOfLostFrames > 0 )
989   {
990     WebRtcIsacfix_DecodePlcImpl(outframeWB, &ISAC_inst->ISACdec_obj,
991                                 &no_of_samples);
992 
993     WebRtcIsacfix_SplitAndFilter2(outframeWB, &(outframeNB[k*240]), dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
994 
995     declen += no_of_samples;
996     noOfLostFrames--;
997     k++;
998   }
999 
1000   declen>>=1;
1001 
1002   for (k=0;k<declen;k++) {
1003     decoded[k] = outframeNB[k];
1004   }
1005 
1006   return declen;
1007 }
1008 #endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
1009 
1010 
1011 
1012 
1013 /****************************************************************************
1014  * WebRtcIsacfix_DecodePlc(...)
1015  *
1016  * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
1017  * Output speech length  will be "480*noOfLostFrames" samples
1018  * that is equevalent of "30*noOfLostFrames" millisecond.
1019  *
1020  * Input:
1021  *      - ISAC_main_inst    : ISAC instance.
1022  *      - noOfLostFrames    : Number of PLC frames (480sample = 30ms)
1023  *                                to produce
1024  *
1025  * Output:
1026  *      - decoded           : The decoded vector
1027  *
1028  * Return value             : Number of samples in decoded PLC vector
1029  */
1030 
WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct * ISAC_main_inst,int16_t * decoded,size_t noOfLostFrames)1031 size_t WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct* ISAC_main_inst,
1032                                int16_t* decoded,
1033                                size_t noOfLostFrames)
1034 {
1035 
1036   size_t no_of_samples, declen, k;
1037   int16_t outframe16[MAX_FRAMESAMPLES];
1038 
1039   ISACFIX_SubStruct *ISAC_inst;
1040   /* typecast pointer to real structure */
1041   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1042 
1043   /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
1044   if (noOfLostFrames > 2) {
1045     noOfLostFrames = 2;
1046   }
1047   k = 0;
1048   declen = 0;
1049   while( noOfLostFrames > 0 )
1050   {
1051     WebRtcIsacfix_DecodePlcImpl(&(outframe16[k*480]), &ISAC_inst->ISACdec_obj,
1052                                 &no_of_samples);
1053     declen += no_of_samples;
1054     noOfLostFrames--;
1055     k++;
1056   }
1057 
1058   for (k=0;k<declen;k++) {
1059     decoded[k] = outframe16[k];
1060   }
1061 
1062   return declen;
1063 }
1064 
1065 
1066 /****************************************************************************
1067  * WebRtcIsacfix_Control(...)
1068  *
1069  * This function sets the limit on the short-term average bit rate and the
1070  * frame length. Should be used only in Instantaneous mode.
1071  *
1072  * Input:
1073  *      - ISAC_main_inst    : ISAC instance.
1074  *      - rate              : limit on the short-term average bit rate,
1075  *                            in bits/second (between 10000 and 32000)
1076  *      - framesize         : number of milliseconds per frame (30 or 60)
1077  *
1078  * Return value             : 0  - ok
1079  *                            -1 - Error
1080  */
1081 
WebRtcIsacfix_Control(ISACFIX_MainStruct * ISAC_main_inst,int16_t rate,int framesize)1082 int16_t WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
1083                               int16_t rate,
1084                               int framesize)
1085 {
1086   ISACFIX_SubStruct *ISAC_inst;
1087   /* typecast pointer to real structure */
1088   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1089 
1090   if (ISAC_inst->CodingMode == 0)
1091   {
1092     /* in adaptive mode */
1093     ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1094     return -1;
1095   }
1096 
1097 
1098   if (rate >= 10000 && rate <= 32000)
1099     ISAC_inst->ISACenc_obj.BottleNeck = rate;
1100   else {
1101     ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1102     return -1;
1103   }
1104 
1105 
1106 
1107   if (framesize  == 30 || framesize == 60)
1108     ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * framesize);
1109   else {
1110     ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1111     return -1;
1112   }
1113 
1114   return 0;
1115 }
1116 
WebRtcIsacfix_SetInitialBweBottleneck(ISACFIX_MainStruct * ISAC_main_inst,int bottleneck_bits_per_second)1117 void WebRtcIsacfix_SetInitialBweBottleneck(ISACFIX_MainStruct* ISAC_main_inst,
1118                                            int bottleneck_bits_per_second) {
1119   ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
1120   assert(bottleneck_bits_per_second >= 10000 &&
1121          bottleneck_bits_per_second <= 32000);
1122   inst->bwestimator_obj.sendBwAvg = ((uint32_t)bottleneck_bits_per_second) << 7;
1123 }
1124 
1125 /****************************************************************************
1126  * WebRtcIsacfix_ControlBwe(...)
1127  *
1128  * This function sets the initial values of bottleneck and frame-size if
1129  * iSAC is used in channel-adaptive mode. Through this API, users can
1130  * enforce a frame-size for all values of bottleneck. Then iSAC will not
1131  * automatically change the frame-size.
1132  *
1133  *
1134  * Input:
1135  *  - ISAC_main_inst : ISAC instance.
1136  *      - rateBPS           : initial value of bottleneck in bits/second
1137  *                            10000 <= rateBPS <= 32000 is accepted
1138  *                            For default bottleneck set rateBPS = 0
1139  *      - frameSizeMs       : number of milliseconds per frame (30 or 60)
1140  *      - enforceFrameSize  : 1 to enforce the given frame-size through out
1141  *                            the adaptation process, 0 to let iSAC change
1142  *                            the frame-size if required.
1143  *
1144  * Return value    : 0  - ok
1145  *         -1 - Error
1146  */
1147 
WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct * ISAC_main_inst,int16_t rateBPS,int frameSizeMs,int16_t enforceFrameSize)1148 int16_t WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
1149                                  int16_t rateBPS,
1150                                  int frameSizeMs,
1151                                  int16_t enforceFrameSize)
1152 {
1153   ISACFIX_SubStruct *ISAC_inst;
1154   /* Typecast pointer to real structure */
1155   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1156 
1157   /* check if encoder initiated */
1158   if ((ISAC_inst->initflag & 2) != 2) {
1159     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
1160     return (-1);
1161   }
1162 
1163   /* Check that we are in channel-adaptive mode, otherwise, return -1 */
1164   if (ISAC_inst->CodingMode != 0) {
1165     ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1166     return (-1);
1167   }
1168 
1169   /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */
1170   /* chosen frame size.                                                      */
1171   ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0;
1172 
1173   /* Set initial rate, if value between 10000 and 32000,                */
1174   /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
1175   if ((rateBPS >= 10000) && (rateBPS <= 32000)) {
1176     ISAC_inst->bwestimator_obj.sendBwAvg = (((uint32_t)rateBPS) << 7);
1177   } else if (rateBPS != 0) {
1178     ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1179     return -1;
1180   }
1181 
1182   /* Set initial framesize. If enforceFrameSize is set the frame size will not change */
1183   if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
1184     ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * frameSizeMs);
1185   } else {
1186     ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1187     return -1;
1188   }
1189 
1190   return 0;
1191 }
1192 
1193 
1194 
1195 
1196 
1197 /****************************************************************************
1198  * WebRtcIsacfix_GetDownLinkBwIndex(...)
1199  *
1200  * This function returns index representing the Bandwidth estimate from
1201  * other side to this side.
1202  *
1203  * Input:
1204  *      - ISAC_main_inst: iSAC struct
1205  *
1206  * Output:
1207  *      - rateIndex     : Bandwidth estimate to transmit to other side.
1208  *
1209  */
1210 
WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct * ISAC_main_inst,int16_t * rateIndex)1211 int16_t WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
1212                                          int16_t*     rateIndex)
1213 {
1214   ISACFIX_SubStruct *ISAC_inst;
1215 
1216   /* typecast pointer to real structure */
1217   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1218 
1219   /* Call function to get Bandwidth Estimate */
1220   *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj);
1221 
1222   return 0;
1223 }
1224 
1225 
1226 /****************************************************************************
1227  * WebRtcIsacfix_UpdateUplinkBw(...)
1228  *
1229  * This function takes an index representing the Bandwidth estimate from
1230  * this side to other side and updates BWE.
1231  *
1232  * Input:
1233  *      - ISAC_main_inst: iSAC struct
1234  *      - rateIndex     : Bandwidth estimate from other side.
1235  *
1236  */
1237 
WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct * ISAC_main_inst,int16_t rateIndex)1238 int16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
1239                                      int16_t     rateIndex)
1240 {
1241   int16_t err = 0;
1242   ISACFIX_SubStruct *ISAC_inst;
1243 
1244   /* typecast pointer to real structure */
1245   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1246 
1247   /* Call function to update BWE with received Bandwidth Estimate */
1248   err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex);
1249   if (err < 0) {
1250     ISAC_inst->errorcode = -err;
1251     return (-1);
1252   }
1253 
1254   return 0;
1255 }
1256 
1257 /****************************************************************************
1258  * WebRtcIsacfix_ReadFrameLen(...)
1259  *
1260  * This function returns the length of the frame represented in the packet.
1261  *
1262  * Input:
1263  *      - encoded       : Encoded bitstream
1264  *
1265  * Output:
1266  *      - frameLength   : Length of frame in packet (in samples)
1267  *
1268  */
1269 
WebRtcIsacfix_ReadFrameLen(const uint8_t * encoded,size_t encoded_len_bytes,size_t * frameLength)1270 int16_t WebRtcIsacfix_ReadFrameLen(const uint8_t* encoded,
1271                                    size_t encoded_len_bytes,
1272                                    size_t* frameLength)
1273 {
1274   Bitstr_dec streamdata;
1275   int16_t err;
1276   const size_t kRequiredEncodedLenBytes = 10;
1277 
1278   if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1279     return -1;
1280   }
1281 
1282   InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1283 
1284   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1285 
1286   /* decode frame length */
1287   err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
1288   if (err<0)  // error check
1289     return err;
1290 
1291   return 0;
1292 }
1293 
1294 
1295 /****************************************************************************
1296  * WebRtcIsacfix_ReadBwIndex(...)
1297  *
1298  * This function returns the index of the Bandwidth estimate from the bitstream.
1299  *
1300  * Input:
1301  *      - encoded       : Encoded bitstream
1302  *
1303  * Output:
1304  *      - frameLength   : Length of frame in packet (in samples)
1305  *      - rateIndex     : Bandwidth estimate in bitstream
1306  *
1307  */
1308 
WebRtcIsacfix_ReadBwIndex(const uint8_t * encoded,size_t encoded_len_bytes,int16_t * rateIndex)1309 int16_t WebRtcIsacfix_ReadBwIndex(const uint8_t* encoded,
1310                                   size_t encoded_len_bytes,
1311                                   int16_t* rateIndex)
1312 {
1313   Bitstr_dec streamdata;
1314   int16_t err;
1315   const size_t kRequiredEncodedLenBytes = 10;
1316 
1317   if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1318     return -1;
1319   }
1320 
1321   InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1322 
1323   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1324 
1325   /* decode frame length, needed to get to the rateIndex in the bitstream */
1326   size_t frameLength;
1327   err = WebRtcIsacfix_DecodeFrameLen(&streamdata, &frameLength);
1328   if (err<0)  // error check
1329     return err;
1330 
1331   /* decode BW estimation */
1332   err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex);
1333   if (err<0)  // error check
1334     return err;
1335 
1336   return 0;
1337 }
1338 
1339 
1340 
1341 
1342 /****************************************************************************
1343  * WebRtcIsacfix_GetErrorCode(...)
1344  *
1345  * This function can be used to check the error code of an iSAC instance. When
1346  * a function returns -1 a error code will be set for that instance. The
1347  * function below extract the code of the last error that occured in the
1348  * specified instance.
1349  *
1350  * Input:
1351  *      - ISAC_main_inst    : ISAC instance
1352  *
1353  * Return value             : Error code
1354  */
1355 
WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct * ISAC_main_inst)1356 int16_t WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst)
1357 {
1358   ISACFIX_SubStruct *ISAC_inst;
1359   /* typecast pointer to real structure */
1360   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1361 
1362   return ISAC_inst->errorcode;
1363 }
1364 
1365 
1366 
1367 /****************************************************************************
1368  * WebRtcIsacfix_GetUplinkBw(...)
1369  *
1370  * This function returns the inst quantized iSAC send bitrate
1371  *
1372  * Input:
1373  *      - ISAC_main_inst    : iSAC instance
1374  *
1375  * Return value             : bitrate
1376  */
1377 
WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct * ISAC_main_inst)1378 int32_t WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst)
1379 {
1380   ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1381   BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj);
1382 
1383   return (int32_t) WebRtcIsacfix_GetUplinkBandwidth(bw);
1384 }
1385 
1386 /****************************************************************************
1387  * WebRtcIsacfix_GetNewFrameLen(...)
1388  *
1389  * This function return the next frame length (in samples) of iSAC.
1390  *
1391  * Input:
1392  *      - ISAC_main_inst    : iSAC instance
1393  *
1394  * Return value             :  frame lenght in samples
1395  */
1396 
WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct * ISAC_main_inst)1397 int16_t WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst)
1398 {
1399   ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1400   return ISAC_inst->ISACenc_obj.new_framelength;
1401 }
1402 
1403 
1404 /****************************************************************************
1405  * WebRtcIsacfix_SetMaxPayloadSize(...)
1406  *
1407  * This function sets a limit for the maximum payload size of iSAC. The same
1408  * value is used both for 30 and 60 msec packets.
1409  * The absolute max will be valid until next time the function is called.
1410  * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
1411  *
1412  * Input:
1413  *      - ISAC_main_inst    : iSAC instance
1414  *      - maxPayloadBytes   : maximum size of the payload in bytes
1415  *                            valid values are between 100 and 400 bytes
1416  *
1417  *
1418  * Return value             : 0 if sucessful
1419  *                           -1 if error happens
1420  */
1421 
WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct * ISAC_main_inst,int16_t maxPayloadBytes)1422 int16_t WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
1423                                         int16_t maxPayloadBytes)
1424 {
1425   ISACFIX_SubStruct *ISAC_inst;
1426 
1427   /* typecast pointer to real structure */
1428   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1429 
1430   if((maxPayloadBytes < 100) || (maxPayloadBytes > 400))
1431   {
1432     /* maxPayloadBytes is out of valid range */
1433     return -1;
1434   }
1435   else
1436   {
1437     /* Set new absolute max, which will not change unless this function
1438        is called again with a new value */
1439     ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes;
1440 
1441     /* Set new maximum values for 30 and 60 msec packets */
1442     if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) {
1443       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes;
1444     } else {
1445       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes;
1446     }
1447 
1448     if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) {
1449       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes;
1450     } else {
1451       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1);
1452     }
1453   }
1454   return 0;
1455 }
1456 
1457 
1458 /****************************************************************************
1459  * WebRtcIsacfix_SetMaxRate(...)
1460  *
1461  * This function sets the maximum rate which the codec may not exceed for a
1462  * singel packet. The maximum rate is set in bits per second.
1463  * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
1464  * per 30 msec).
1465  * It is possible to set a maximum rate between 32000 and 53400 bits per second.
1466  *
1467  * The rate limit is valid until next time the function is called.
1468  *
1469  * NOTE! Packet size will never go above the value set if calling
1470  * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
1471  *
1472  * Input:
1473  *      - ISAC_main_inst    : iSAC instance
1474  *      - maxRateInBytes    : maximum rate in bits per second,
1475  *                            valid values are 32000 to 53400 bits
1476  *
1477  * Return value             : 0 if sucessful
1478  *                           -1 if error happens
1479  */
1480 
WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct * ISAC_main_inst,int32_t maxRate)1481 int16_t WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
1482                                  int32_t maxRate)
1483 {
1484   ISACFIX_SubStruct *ISAC_inst;
1485   int16_t maxRateInBytes;
1486 
1487   /* typecast pointer to real structure */
1488   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1489 
1490   if((maxRate < 32000) || (maxRate > 53400))
1491   {
1492     /* maxRate is out of valid range */
1493     return -1;
1494   }
1495   else
1496   {
1497     /* Calculate maximum number of bytes per 30 msec packets for the given
1498        maximum rate. Multiply with 30/1000 to get number of bits per 30 msec,
1499        divide by 8 to get number of bytes per 30 msec:
1500        maxRateInBytes = floor((maxRate * 30/1000) / 8); */
1501     maxRateInBytes = (int16_t)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) );
1502 
1503     /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */
1504     ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes;
1505 
1506     /* For 30 msec packets: if the new limit is below the maximum
1507        payload size, set a new limit */
1508     if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1509       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes;
1510     } else {
1511       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1512     }
1513 
1514     /* For 60 msec packets: if the new limit (times 2) is below the
1515        maximum payload size, set a new limit */
1516     if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1517       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1);
1518     } else {
1519       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1520     }
1521   }
1522 
1523   return 0;
1524 }
1525 
1526 
1527 
1528 /****************************************************************************
1529  * WebRtcIsacfix_version(...)
1530  *
1531  * This function returns the version number.
1532  *
1533  * Output:
1534  *      - version  : Pointer to character string
1535  *
1536  */
1537 
WebRtcIsacfix_version(char * version)1538 void WebRtcIsacfix_version(char *version)
1539 {
1540   strcpy(version, "3.6.0");
1541 }
1542 
WebRtcIsacfix_GetBandwidthInfo(ISACFIX_MainStruct * ISAC_main_inst,IsacBandwidthInfo * bwinfo)1543 void WebRtcIsacfix_GetBandwidthInfo(ISACFIX_MainStruct* ISAC_main_inst,
1544                                     IsacBandwidthInfo* bwinfo) {
1545   ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
1546   assert(inst->initflag & 1);  // Decoder initialized.
1547   WebRtcIsacfixBw_GetBandwidthInfo(&inst->bwestimator_obj, bwinfo);
1548 }
1549 
WebRtcIsacfix_SetBandwidthInfo(ISACFIX_MainStruct * ISAC_main_inst,const IsacBandwidthInfo * bwinfo)1550 void WebRtcIsacfix_SetBandwidthInfo(ISACFIX_MainStruct* ISAC_main_inst,
1551                                     const IsacBandwidthInfo* bwinfo) {
1552   ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
1553   assert(inst->initflag & 2);  // Encoder initialized.
1554   WebRtcIsacfixBw_SetBandwidthInfo(&inst->bwestimator_obj, bwinfo);
1555 }
1556