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 "modules/audio_coding/codecs/isac/fix/include/isacfix.h"
19 
20 #include <stdlib.h>
21 
22 #include "rtc_base/checks.h"
23 #include "modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
24 #include "modules/audio_coding/codecs/isac/fix/source/codec.h"
25 #include "modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
26 #include "modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
27 #include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
28 #include "modules/audio_coding/codecs/isac/fix/source/structs.h"
29 #include "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_Create(...)
53  *
54  * This function creates a ISAC instance, which will contain the state
55  * information for one coding/decoding channel.
56  *
57  * Input:
58  *      - *ISAC_main_inst   : a pointer to the coder instance.
59  *
60  * Return value             :  0 - Ok
61  *                            -1 - Error
62  */
63 
WebRtcIsacfix_Create(ISACFIX_MainStruct ** ISAC_main_inst)64 int16_t WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst)
65 {
66   ISACFIX_SubStruct *tempo;
67   tempo = malloc(1 * sizeof(ISACFIX_SubStruct));
68   *ISAC_main_inst = (ISACFIX_MainStruct *)tempo;
69   if (*ISAC_main_inst!=NULL) {
70     (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0;
71     (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0;
72     (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL;
73     WebRtcIsacfix_InitBandwidthEstimator(&tempo->bwestimator_obj);
74     return(0);
75   } else {
76     return(-1);
77   }
78 }
79 
80 
81 /****************************************************************************
82  * WebRtcIsacfix_CreateInternal(...)
83  *
84  * This function creates the memory that is used to store data in the encoder
85  *
86  * Input:
87  *      - *ISAC_main_inst   : a pointer to the coder instance.
88  *
89  * Return value             :  0 - Ok
90  *                            -1 - Error
91  */
92 
WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct * ISAC_main_inst)93 int16_t WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst)
94 {
95   ISACFIX_SubStruct *ISAC_inst;
96 
97   /* typecast pointer to real structure */
98   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
99 
100   /* Allocate memory for storing encoder data */
101   ISAC_inst->ISACenc_obj.SaveEnc_ptr = malloc(1 * sizeof(IsacSaveEncoderData));
102 
103   if (ISAC_inst->ISACenc_obj.SaveEnc_ptr!=NULL) {
104     return(0);
105   } else {
106     return(-1);
107   }
108 }
109 
110 
111 /****************************************************************************
112  * WebRtcIsacfix_Free(...)
113  *
114  * This function frees the ISAC instance created at the beginning.
115  *
116  * Input:
117  *      - ISAC_main_inst    : a ISAC instance.
118  *
119  * Return value             :  0 - Ok
120  *                            -1 - Error
121  */
122 
WebRtcIsacfix_Free(ISACFIX_MainStruct * ISAC_main_inst)123 int16_t WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst)
124 {
125   free(ISAC_main_inst);
126   return(0);
127 }
128 
129 /****************************************************************************
130  * WebRtcIsacfix_FreeInternal(...)
131  *
132  * This function frees the internal memory for storing encoder data.
133  *
134  * Input:
135  *       - ISAC_main_inst    : a ISAC instance.
136  *
137  * Return value              :  0 - Ok
138  *                             -1 - Error
139  */
140 
WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct * ISAC_main_inst)141 int16_t WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst)
142 {
143   ISACFIX_SubStruct *ISAC_inst;
144 
145   /* typecast pointer to real structure */
146   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
147 
148   /* Release memory */
149   free(ISAC_inst->ISACenc_obj.SaveEnc_ptr);
150 
151   return(0);
152 }
153 
154 /****************************************************************************
155  * WebRtcIsacfix_InitNeon(...)
156  *
157  * This function initializes function pointers for ARM Neon platform.
158  */
159 
160 #if defined(WEBRTC_HAS_NEON)
WebRtcIsacfix_InitNeon(void)161 static void WebRtcIsacfix_InitNeon(void) {
162   WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon;
163   WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon;
164   WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeNeon;
165   WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecNeon;
166   WebRtcIsacfix_AllpassFilter2FixDec16 =
167       WebRtcIsacfix_AllpassFilter2FixDec16Neon;
168   WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1Neon;
169   WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2Neon;
170 }
171 #endif
172 
173 /****************************************************************************
174  * WebRtcIsacfix_InitMIPS(...)
175  *
176  * This function initializes function pointers for MIPS platform.
177  */
178 
179 #if defined(MIPS32_LE)
WebRtcIsacfix_InitMIPS(void)180 static void WebRtcIsacfix_InitMIPS(void) {
181   WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrMIPS;
182   WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopMIPS;
183   WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeMIPS;
184   WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecMIPS;
185   WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1MIPS;
186   WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2MIPS;
187 #if defined(MIPS_DSP_R1_LE)
188   WebRtcIsacfix_AllpassFilter2FixDec16 =
189       WebRtcIsacfix_AllpassFilter2FixDec16MIPS;
190   WebRtcIsacfix_HighpassFilterFixDec32 =
191       WebRtcIsacfix_HighpassFilterFixDec32MIPS;
192 #endif
193 #if defined(MIPS_DSP_R2_LE)
194   WebRtcIsacfix_CalculateResidualEnergy =
195       WebRtcIsacfix_CalculateResidualEnergyMIPS;
196 #endif
197 }
198 #endif
199 
InitFunctionPointers(void)200 static void InitFunctionPointers(void) {
201   WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
202   WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
203   WebRtcIsacfix_CalculateResidualEnergy =
204       WebRtcIsacfix_CalculateResidualEnergyC;
205   WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
206   WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
207   WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
208   WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
209   WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
210   WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
211 
212 #if defined(WEBRTC_HAS_NEON)
213   WebRtcIsacfix_InitNeon();
214 #endif
215 
216 #if defined(MIPS32_LE)
217   WebRtcIsacfix_InitMIPS();
218 #endif
219 }
220 
221 /****************************************************************************
222  * WebRtcIsacfix_EncoderInit(...)
223  *
224  * This function initializes a ISAC instance prior to the encoder calls.
225  *
226  * Input:
227  *      - ISAC_main_inst    : ISAC instance.
228  *      - CodingMode        : 0 -> Bit rate and frame length are automatically
229  *                                 adjusted to available bandwidth on
230  *                                 transmission channel.
231  *                            1 -> User sets a frame length and a target bit
232  *                                 rate which is taken as the maximum short-term
233  *                                 average bit rate.
234  *
235  * Return value             :  0 - Ok
236  *                            -1 - Error
237  */
238 
WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct * ISAC_main_inst,int16_t CodingMode)239 int16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
240                                   int16_t  CodingMode)
241 {
242   int k;
243   int16_t statusInit;
244   ISACFIX_SubStruct *ISAC_inst;
245 
246   statusInit = 0;
247   /* typecast pointer to rela structure */
248   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
249 
250   /* flag encoder init */
251   ISAC_inst->initflag |= 2;
252 
253   if (CodingMode == 0)
254     /* Adaptive mode */
255     ISAC_inst->ISACenc_obj.new_framelength  = INITIAL_FRAMESAMPLES;
256   else if (CodingMode == 1)
257     /* Instantaneous mode */
258     ISAC_inst->ISACenc_obj.new_framelength = 480;    /* default for I-mode */
259   else {
260     ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE;
261     statusInit = -1;
262   }
263 
264   ISAC_inst->CodingMode = CodingMode;
265 
266   WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj);
267   WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj);
268   WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj);
269   WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj);
270 
271   WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj);
272 
273 
274   ISAC_inst->ISACenc_obj.buffer_index   = 0;
275   ISAC_inst->ISACenc_obj.frame_nb    = 0;
276   ISAC_inst->ISACenc_obj.BottleNeck      = 32000; /* default for I-mode */
277   ISAC_inst->ISACenc_obj.MaxDelay    = 10;    /* default for I-mode */
278   ISAC_inst->ISACenc_obj.current_framesamples = 0;
279   ISAC_inst->ISACenc_obj.s2nr     = 0;
280   ISAC_inst->ISACenc_obj.MaxBits    = 0;
281   ISAC_inst->ISACenc_obj.bitstr_seed   = 4447;
282   ISAC_inst->ISACenc_obj.payloadLimitBytes30  = STREAM_MAXW16_30MS << 1;
283   ISAC_inst->ISACenc_obj.payloadLimitBytes60  = STREAM_MAXW16_60MS << 1;
284   ISAC_inst->ISACenc_obj.maxPayloadBytes      = STREAM_MAXW16_60MS << 1;
285   ISAC_inst->ISACenc_obj.maxRateInBytes       = STREAM_MAXW16_30MS << 1;
286   ISAC_inst->ISACenc_obj.enforceFrameSize     = 0;
287 
288   /* Init the bistream data area to zero */
289   for (k=0; k<STREAM_MAXW16_60MS; k++){
290     ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0;
291   }
292 
293   InitFunctionPointers();
294 
295   return statusInit;
296 }
297 
298 /* Read the given number of bytes of big-endian 16-bit integers from |src| and
299    write them to |dest| in host endian. If |nbytes| is odd, the number of
300    output elements is rounded up, and the least significant byte of the last
301    element is set to 0. */
read_be16(const uint8_t * src,size_t nbytes,uint16_t * dest)302 static void read_be16(const uint8_t* src, size_t nbytes, uint16_t* dest) {
303   size_t i;
304   for (i = 0; i < nbytes / 2; ++i)
305     dest[i] = src[2 * i] << 8 | src[2 * i + 1];
306   if (nbytes % 2 == 1)
307     dest[nbytes / 2] = src[nbytes - 1] << 8;
308 }
309 
310 /* Read the given number of bytes of host-endian 16-bit integers from |src| and
311    write them to |dest| in big endian. If |nbytes| is odd, the number of source
312    elements is rounded up (but only the most significant byte of the last
313    element is used), and the number of output bytes written will be
314    nbytes + 1. */
write_be16(const uint16_t * src,size_t nbytes,uint8_t * dest)315 static void write_be16(const uint16_t* src, size_t nbytes, uint8_t* dest) {
316   size_t i;
317   for (i = 0; i < nbytes / 2; ++i) {
318     dest[2 * i] = src[i] >> 8;
319     dest[2 * i + 1] = src[i];
320   }
321   if (nbytes % 2 == 1) {
322     dest[nbytes - 1] = src[nbytes / 2] >> 8;
323     dest[nbytes] = 0;
324   }
325 }
326 
327 /****************************************************************************
328  * WebRtcIsacfix_Encode(...)
329  *
330  * This function encodes 10ms frame(s) and inserts it into a package.
331  * Input speech length has to be 160 samples (10ms). The encoder buffers those
332  * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
333  * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
334  *
335  * Input:
336  *      - ISAC_main_inst    : ISAC instance.
337  *      - speechIn          : input speech vector.
338  *
339  * Output:
340  *      - encoded           : the encoded data vector
341  *
342  * Return value:
343  *                          : >0 - Length (in bytes) of coded data
344  *                          :  0 - The buffer didn't reach the chosen framesize
345  *                            so it keeps buffering speech samples.
346  *                          : -1 - Error
347  */
348 
WebRtcIsacfix_Encode(ISACFIX_MainStruct * ISAC_main_inst,const int16_t * speechIn,uint8_t * encoded)349 int WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
350                          const int16_t    *speechIn,
351                          uint8_t* encoded)
352 {
353   ISACFIX_SubStruct *ISAC_inst;
354   int stream_len;
355 
356   /* typecast pointer to rela structure */
357   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
358 
359 
360   /* check if encoder initiated */
361   if ((ISAC_inst->initflag & 2) != 2) {
362     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
363     return (-1);
364   }
365 
366   stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechIn,
367                                         &ISAC_inst->ISACenc_obj,
368                                         &ISAC_inst->bwestimator_obj,
369                                         ISAC_inst->CodingMode);
370   if (stream_len<0) {
371     ISAC_inst->errorcode = -(int16_t)stream_len;
372     return -1;
373   }
374 
375   write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, (size_t)stream_len,
376              encoded);
377   return stream_len;
378 
379 }
380 
381 
382 /****************************************************************************
383  * WebRtcIsacfix_GetNewBitStream(...)
384  *
385  * This function returns encoded data, with the recieved bwe-index in the
386  * stream. It should always return a complete packet, i.e. only called once
387  * even for 60 msec frames
388  *
389  * Input:
390  *      - ISAC_main_inst    : ISAC instance.
391  *      - bweIndex          : index of bandwidth estimate to put in new bitstream
392  *
393  * Output:
394  *      - encoded           : the encoded data vector
395  *
396  * Return value:
397  *                          : >0 - Length (in bytes) of coded data
398  *                          : -1 - Error
399  */
400 
WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct * ISAC_main_inst,int16_t bweIndex,float scale,uint8_t * encoded)401 int16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
402                                       int16_t      bweIndex,
403                                       float              scale,
404                                       uint8_t* encoded)
405 {
406   ISACFIX_SubStruct *ISAC_inst;
407   int16_t stream_len;
408 
409   /* typecast pointer to rela structure */
410   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
411 
412 
413   /* check if encoder initiated */
414   if ((ISAC_inst->initflag & 2) != 2) {
415     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
416     return (-1);
417   }
418 
419   stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj,
420                                               bweIndex,
421                                               scale);
422   if (stream_len<0) {
423     ISAC_inst->errorcode = - stream_len;
424     return -1;
425   }
426 
427   write_be16(ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len, encoded);
428   return stream_len;
429 }
430 
431 
432 
433 /****************************************************************************
434  * WebRtcIsacfix_DecoderInit(...)
435  *
436  * This function initializes a ISAC instance prior to the decoder calls.
437  *
438  * Input:
439  *      - ISAC_main_inst    : ISAC instance.
440  */
441 
WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct * ISAC_main_inst)442 void WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst)
443 {
444   ISACFIX_SubStruct *ISAC_inst;
445 
446   InitFunctionPointers();
447 
448   /* typecast pointer to real structure */
449   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
450 
451   /* flag decoder init */
452   ISAC_inst->initflag |= 1;
453 
454   WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj);
455   WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj);
456   WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj);
457 
458   /* TS */
459   WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj );
460 }
461 
462 
463 /****************************************************************************
464  * WebRtcIsacfix_UpdateBwEstimate1(...)
465  *
466  * This function updates the estimate of the bandwidth.
467  *
468  * Input:
469  *      - ISAC_main_inst    : ISAC instance.
470  *      - encoded           : encoded ISAC frame(s).
471  *      - packet_size       : size of the packet.
472  *      - rtp_seq_number    : the RTP number of the packet.
473  *      - arr_ts            : the arrival time of the packet (from NetEq)
474  *                            in samples.
475  *
476  * Return value             :  0 - Ok
477  *                            -1 - Error
478  */
479 
WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct * ISAC_main_inst,const uint8_t * encoded,size_t packet_size,uint16_t rtp_seq_number,uint32_t arr_ts)480 int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
481                                         const uint8_t* encoded,
482                                         size_t packet_size,
483                                         uint16_t rtp_seq_number,
484                                         uint32_t arr_ts)
485 {
486   ISACFIX_SubStruct *ISAC_inst;
487   Bitstr_dec streamdata;
488   int16_t err;
489   const size_t kRequiredEncodedLenBytes = 10;
490 
491   /* typecast pointer to real structure */
492   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
493 
494   /* Sanity check of packet length */
495   if (packet_size == 0) {
496     /* return error code if the packet length is null or less */
497     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
498     return -1;
499   } else if (packet_size > (STREAM_MAXW16<<1)) {
500     /* return error code if length of stream is too long */
501     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
502     return -1;
503   }
504 
505   /* check if decoder initiated */
506   if ((ISAC_inst->initflag & 1) != 1) {
507     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
508     return (-1);
509   }
510 
511   InitializeDecoderBitstream(packet_size, &streamdata);
512 
513   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
514 
515   err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
516                                         &streamdata,
517                                         packet_size,
518                                         rtp_seq_number,
519                                         0,
520                                         arr_ts);
521 
522 
523   if (err < 0)
524   {
525     /* return error code if something went wrong */
526     ISAC_inst->errorcode = -err;
527     return -1;
528   }
529 
530 
531   return 0;
532 }
533 
534 /****************************************************************************
535  * WebRtcIsacfix_UpdateBwEstimate(...)
536  *
537  * This function updates the estimate of the bandwidth.
538  *
539  * Input:
540  *      - ISAC_main_inst    : ISAC instance.
541  *      - encoded           : encoded ISAC frame(s).
542  *      - packet_size       : size of the packet.
543  *      - rtp_seq_number    : the RTP number of the packet.
544  *      - send_ts           : Send Time Stamp from RTP header
545  *      - arr_ts            : the arrival time of the packet (from NetEq)
546  *                            in samples.
547  *
548  * Return value             :  0 - Ok
549  *                            -1 - Error
550  */
551 
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)552 int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
553                                        const uint8_t* encoded,
554                                        size_t packet_size,
555                                        uint16_t rtp_seq_number,
556                                        uint32_t send_ts,
557                                        uint32_t arr_ts)
558 {
559   ISACFIX_SubStruct *ISAC_inst;
560   Bitstr_dec streamdata;
561   int16_t err;
562   const size_t kRequiredEncodedLenBytes = 10;
563 
564   /* typecast pointer to real structure */
565   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
566 
567   /* Sanity check of packet length */
568   if (packet_size == 0) {
569     /* return error code if the packet length is null  or less */
570     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
571     return -1;
572   } else if (packet_size < kRequiredEncodedLenBytes) {
573     ISAC_inst->errorcode = ISAC_PACKET_TOO_SHORT;
574     return -1;
575   } else if (packet_size > (STREAM_MAXW16<<1)) {
576     /* return error code if length of stream is too long */
577     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
578     return -1;
579   }
580 
581   /* check if decoder initiated */
582   if ((ISAC_inst->initflag & 1) != 1) {
583     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
584     return (-1);
585   }
586 
587   InitializeDecoderBitstream(packet_size, &streamdata);
588 
589   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
590 
591   err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
592                                         &streamdata,
593                                         packet_size,
594                                         rtp_seq_number,
595                                         send_ts,
596                                         arr_ts);
597 
598   if (err < 0)
599   {
600     /* return error code if something went wrong */
601     ISAC_inst->errorcode = -err;
602     return -1;
603   }
604 
605 
606   return 0;
607 }
608 
609 /****************************************************************************
610  * WebRtcIsacfix_Decode(...)
611  *
612  * This function decodes a ISAC frame. Output speech length
613  * will be a multiple of 480 samples: 480 or 960 samples,
614  * depending on the framesize (30 or 60 ms).
615  *
616  * Input:
617  *      - ISAC_main_inst    : ISAC instance.
618  *      - encoded           : encoded ISAC frame(s)
619  *      - len               : bytes in encoded vector
620  *
621  * Output:
622  *      - decoded           : The decoded vector
623  *
624  * Return value             : >0 - number of samples in decoded vector
625  *                            -1 - Error
626  */
627 
628 
WebRtcIsacfix_Decode(ISACFIX_MainStruct * ISAC_main_inst,const uint8_t * encoded,size_t len,int16_t * decoded,int16_t * speechType)629 int WebRtcIsacfix_Decode(ISACFIX_MainStruct* ISAC_main_inst,
630                          const uint8_t* encoded,
631                          size_t len,
632                          int16_t* decoded,
633                          int16_t* speechType)
634 {
635   ISACFIX_SubStruct *ISAC_inst;
636   /* number of samples (480 or 960), output from decoder */
637   /* that were actually used in the encoder/decoder (determined on the fly) */
638   size_t number_of_samples;
639   int declen_int = 0;
640   size_t declen;
641 
642   /* typecast pointer to real structure */
643   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
644 
645   /* check if decoder initiated */
646   if ((ISAC_inst->initflag & 1) != 1) {
647     ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
648     return (-1);
649   }
650 
651   /* Sanity check of packet length */
652   if (len == 0) {
653     /* return error code if the packet length is null  or less */
654     ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
655     return -1;
656   } else if (len > (STREAM_MAXW16<<1)) {
657     /* return error code if length of stream is too long */
658     ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
659     return -1;
660   }
661 
662   InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
663 
664   read_be16(encoded, len, ISAC_inst->ISACdec_obj.bitstr_obj.stream);
665 
666   /* added for NetEq purposes (VAD/DTX related) */
667   *speechType=1;
668 
669   declen_int = WebRtcIsacfix_DecodeImpl(decoded, &ISAC_inst->ISACdec_obj,
670                                         &number_of_samples);
671   if (declen_int < 0) {
672     /* Some error inside the decoder */
673     ISAC_inst->errorcode = -(int16_t)declen_int;
674     memset(decoded, 0, sizeof(int16_t) * MAX_FRAMESAMPLES);
675     return -1;
676   }
677   declen = (size_t)declen_int;
678 
679   /* error check */
680 
681   if (declen & 1) {
682     if (len != declen &&
683         len != declen +
684             ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) & 0xFF)) {
685       ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
686       memset(decoded, 0, sizeof(int16_t) * number_of_samples);
687       return -1;
688     }
689   } else {
690     if (len != declen &&
691         len != declen +
692             ((ISAC_inst->ISACdec_obj.bitstr_obj.stream[declen >> 1]) >> 8)) {
693       ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
694       memset(decoded, 0, sizeof(int16_t) * number_of_samples);
695       return -1;
696     }
697   }
698 
699   return (int)number_of_samples;
700 }
701 
702 
703 /****************************************************************************
704  * WebRtcIsacfix_DecodePlc(...)
705  *
706  * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
707  * Output speech length  will be "480*noOfLostFrames" samples
708  * that is equevalent of "30*noOfLostFrames" millisecond.
709  *
710  * Input:
711  *      - ISAC_main_inst    : ISAC instance.
712  *      - noOfLostFrames    : Number of PLC frames (480sample = 30ms)
713  *                                to produce
714  *
715  * Output:
716  *      - decoded           : The decoded vector
717  *
718  * Return value             : Number of samples in decoded PLC vector
719  */
720 
WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct * ISAC_main_inst,int16_t * decoded,size_t noOfLostFrames)721 size_t WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct* ISAC_main_inst,
722                                int16_t* decoded,
723                                size_t noOfLostFrames)
724 {
725 
726   size_t no_of_samples, declen, k;
727   int16_t outframe16[MAX_FRAMESAMPLES];
728 
729   ISACFIX_SubStruct *ISAC_inst;
730   /* typecast pointer to real structure */
731   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
732 
733   /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
734   if (noOfLostFrames > 2) {
735     noOfLostFrames = 2;
736   }
737   k = 0;
738   declen = 0;
739   while( noOfLostFrames > 0 )
740   {
741     WebRtcIsacfix_DecodePlcImpl(&(outframe16[k*480]), &ISAC_inst->ISACdec_obj,
742                                 &no_of_samples);
743     declen += no_of_samples;
744     noOfLostFrames--;
745     k++;
746   }
747 
748   for (k=0;k<declen;k++) {
749     decoded[k] = outframe16[k];
750   }
751 
752   return declen;
753 }
754 
755 
756 /****************************************************************************
757  * WebRtcIsacfix_Control(...)
758  *
759  * This function sets the limit on the short-term average bit rate and the
760  * frame length. Should be used only in Instantaneous mode.
761  *
762  * Input:
763  *      - ISAC_main_inst    : ISAC instance.
764  *      - rate              : limit on the short-term average bit rate,
765  *                            in bits/second (between 10000 and 32000)
766  *      - framesize         : number of milliseconds per frame (30 or 60)
767  *
768  * Return value             : 0  - ok
769  *                            -1 - Error
770  */
771 
WebRtcIsacfix_Control(ISACFIX_MainStruct * ISAC_main_inst,int16_t rate,int framesize)772 int16_t WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
773                               int16_t rate,
774                               int framesize)
775 {
776   ISACFIX_SubStruct *ISAC_inst;
777   /* typecast pointer to real structure */
778   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
779 
780   if (ISAC_inst->CodingMode == 0)
781   {
782     /* in adaptive mode */
783     ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
784     return -1;
785   }
786 
787 
788   if (rate >= 10000 && rate <= 32000)
789     ISAC_inst->ISACenc_obj.BottleNeck = rate;
790   else {
791     ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
792     return -1;
793   }
794 
795 
796 
797   if (framesize  == 30 || framesize == 60)
798     ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * framesize);
799   else {
800     ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
801     return -1;
802   }
803 
804   return 0;
805 }
806 
WebRtcIsacfix_SetInitialBweBottleneck(ISACFIX_MainStruct * ISAC_main_inst,int bottleneck_bits_per_second)807 void WebRtcIsacfix_SetInitialBweBottleneck(ISACFIX_MainStruct* ISAC_main_inst,
808                                            int bottleneck_bits_per_second) {
809   ISACFIX_SubStruct* inst = (ISACFIX_SubStruct*)ISAC_main_inst;
810   RTC_DCHECK_GE(bottleneck_bits_per_second, 10000);
811   RTC_DCHECK_LE(bottleneck_bits_per_second, 32000);
812   inst->bwestimator_obj.sendBwAvg = ((uint32_t)bottleneck_bits_per_second) << 7;
813 }
814 
815 /****************************************************************************
816  * WebRtcIsacfix_ControlBwe(...)
817  *
818  * This function sets the initial values of bottleneck and frame-size if
819  * iSAC is used in channel-adaptive mode. Through this API, users can
820  * enforce a frame-size for all values of bottleneck. Then iSAC will not
821  * automatically change the frame-size.
822  *
823  *
824  * Input:
825  *  - ISAC_main_inst : ISAC instance.
826  *      - rateBPS           : initial value of bottleneck in bits/second
827  *                            10000 <= rateBPS <= 32000 is accepted
828  *                            For default bottleneck set rateBPS = 0
829  *      - frameSizeMs       : number of milliseconds per frame (30 or 60)
830  *      - enforceFrameSize  : 1 to enforce the given frame-size through out
831  *                            the adaptation process, 0 to let iSAC change
832  *                            the frame-size if required.
833  *
834  * Return value    : 0  - ok
835  *         -1 - Error
836  */
837 
WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct * ISAC_main_inst,int16_t rateBPS,int frameSizeMs,int16_t enforceFrameSize)838 int16_t WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
839                                  int16_t rateBPS,
840                                  int frameSizeMs,
841                                  int16_t enforceFrameSize)
842 {
843   ISACFIX_SubStruct *ISAC_inst;
844   /* Typecast pointer to real structure */
845   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
846 
847   /* check if encoder initiated */
848   if ((ISAC_inst->initflag & 2) != 2) {
849     ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
850     return (-1);
851   }
852 
853   /* Check that we are in channel-adaptive mode, otherwise, return -1 */
854   if (ISAC_inst->CodingMode != 0) {
855     ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
856     return (-1);
857   }
858 
859   /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */
860   /* chosen frame size.                                                      */
861   ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0;
862 
863   /* Set initial rate, if value between 10000 and 32000,                */
864   /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
865   if ((rateBPS >= 10000) && (rateBPS <= 32000)) {
866     ISAC_inst->bwestimator_obj.sendBwAvg = (((uint32_t)rateBPS) << 7);
867   } else if (rateBPS != 0) {
868     ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
869     return -1;
870   }
871 
872   /* Set initial framesize. If enforceFrameSize is set the frame size will not change */
873   if ((frameSizeMs  == 30) || (frameSizeMs == 60)) {
874     ISAC_inst->ISACenc_obj.new_framelength = (int16_t)((FS/1000) * frameSizeMs);
875   } else {
876     ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
877     return -1;
878   }
879 
880   return 0;
881 }
882 
883 
884 
885 
886 
887 /****************************************************************************
888  * WebRtcIsacfix_GetDownLinkBwIndex(...)
889  *
890  * This function returns index representing the Bandwidth estimate from
891  * other side to this side.
892  *
893  * Input:
894  *      - ISAC_main_inst: iSAC struct
895  *
896  * Output:
897  *      - rateIndex     : Bandwidth estimate to transmit to other side.
898  *
899  */
900 
WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct * ISAC_main_inst,int16_t * rateIndex)901 int16_t WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
902                                          int16_t*     rateIndex)
903 {
904   ISACFIX_SubStruct *ISAC_inst;
905 
906   /* typecast pointer to real structure */
907   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
908 
909   /* Call function to get Bandwidth Estimate */
910   *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj);
911 
912   return 0;
913 }
914 
915 
916 /****************************************************************************
917  * WebRtcIsacfix_UpdateUplinkBw(...)
918  *
919  * This function takes an index representing the Bandwidth estimate from
920  * this side to other side and updates BWE.
921  *
922  * Input:
923  *      - ISAC_main_inst: iSAC struct
924  *      - rateIndex     : Bandwidth estimate from other side.
925  *
926  */
927 
WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct * ISAC_main_inst,int16_t rateIndex)928 int16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
929                                      int16_t     rateIndex)
930 {
931   int16_t err = 0;
932   ISACFIX_SubStruct *ISAC_inst;
933 
934   /* typecast pointer to real structure */
935   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
936 
937   /* Call function to update BWE with received Bandwidth Estimate */
938   err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex);
939   if (err < 0) {
940     ISAC_inst->errorcode = -err;
941     return (-1);
942   }
943 
944   return 0;
945 }
946 
947 /****************************************************************************
948  * WebRtcIsacfix_ReadFrameLen(...)
949  *
950  * This function returns the length of the frame represented in the packet.
951  *
952  * Input:
953  *      - encoded       : Encoded bitstream
954  *
955  * Output:
956  *      - frameLength   : Length of frame in packet (in samples)
957  *
958  */
959 
WebRtcIsacfix_ReadFrameLen(const uint8_t * encoded,size_t encoded_len_bytes,size_t * frameLength)960 int16_t WebRtcIsacfix_ReadFrameLen(const uint8_t* encoded,
961                                    size_t encoded_len_bytes,
962                                    size_t* frameLength)
963 {
964   Bitstr_dec streamdata;
965   int16_t err;
966   const size_t kRequiredEncodedLenBytes = 10;
967 
968   if (encoded_len_bytes < kRequiredEncodedLenBytes) {
969     return -1;
970   }
971 
972   InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
973 
974   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
975 
976   /* decode frame length */
977   err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
978   if (err<0)  // error check
979     return err;
980 
981   return 0;
982 }
983 
984 
985 /****************************************************************************
986  * WebRtcIsacfix_ReadBwIndex(...)
987  *
988  * This function returns the index of the Bandwidth estimate from the bitstream.
989  *
990  * Input:
991  *      - encoded       : Encoded bitstream
992  *
993  * Output:
994  *      - frameLength   : Length of frame in packet (in samples)
995  *      - rateIndex     : Bandwidth estimate in bitstream
996  *
997  */
998 
WebRtcIsacfix_ReadBwIndex(const uint8_t * encoded,size_t encoded_len_bytes,int16_t * rateIndex)999 int16_t WebRtcIsacfix_ReadBwIndex(const uint8_t* encoded,
1000                                   size_t encoded_len_bytes,
1001                                   int16_t* rateIndex)
1002 {
1003   Bitstr_dec streamdata;
1004   int16_t err;
1005   const size_t kRequiredEncodedLenBytes = 10;
1006 
1007   if (encoded_len_bytes < kRequiredEncodedLenBytes) {
1008     return -1;
1009   }
1010 
1011   InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
1012 
1013   read_be16(encoded, kRequiredEncodedLenBytes, streamdata.stream);
1014 
1015   /* decode frame length, needed to get to the rateIndex in the bitstream */
1016   size_t frameLength;
1017   err = WebRtcIsacfix_DecodeFrameLen(&streamdata, &frameLength);
1018   if (err<0)  // error check
1019     return err;
1020 
1021   /* decode BW estimation */
1022   err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex);
1023   if (err<0)  // error check
1024     return err;
1025 
1026   return 0;
1027 }
1028 
1029 
1030 
1031 
1032 /****************************************************************************
1033  * WebRtcIsacfix_GetErrorCode(...)
1034  *
1035  * This function can be used to check the error code of an iSAC instance. When
1036  * a function returns -1 a error code will be set for that instance. The
1037  * function below extract the code of the last error that occured in the
1038  * specified instance.
1039  *
1040  * Input:
1041  *      - ISAC_main_inst    : ISAC instance
1042  *
1043  * Return value             : Error code
1044  */
1045 
WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct * ISAC_main_inst)1046 int16_t WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst)
1047 {
1048   ISACFIX_SubStruct *ISAC_inst;
1049   /* typecast pointer to real structure */
1050   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1051 
1052   return ISAC_inst->errorcode;
1053 }
1054 
1055 
1056 
1057 /****************************************************************************
1058  * WebRtcIsacfix_GetUplinkBw(...)
1059  *
1060  * This function returns the inst quantized iSAC send bitrate
1061  *
1062  * Input:
1063  *      - ISAC_main_inst    : iSAC instance
1064  *
1065  * Return value             : bitrate
1066  */
1067 
WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct * ISAC_main_inst)1068 int32_t WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst)
1069 {
1070   ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1071   BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj);
1072 
1073   return (int32_t) WebRtcIsacfix_GetUplinkBandwidth(bw);
1074 }
1075 
1076 /****************************************************************************
1077  * WebRtcIsacfix_GetNewFrameLen(...)
1078  *
1079  * This function return the next frame length (in samples) of iSAC.
1080  *
1081  * Input:
1082  *      - ISAC_main_inst    : iSAC instance
1083  *
1084  * Return value             :  frame lenght in samples
1085  */
1086 
WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct * ISAC_main_inst)1087 int16_t WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst)
1088 {
1089   ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1090   return ISAC_inst->ISACenc_obj.new_framelength;
1091 }
1092 
1093 
1094 /****************************************************************************
1095  * WebRtcIsacfix_SetMaxPayloadSize(...)
1096  *
1097  * This function sets a limit for the maximum payload size of iSAC. The same
1098  * value is used both for 30 and 60 msec packets.
1099  * The absolute max will be valid until next time the function is called.
1100  * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
1101  *
1102  * Input:
1103  *      - ISAC_main_inst    : iSAC instance
1104  *      - maxPayloadBytes   : maximum size of the payload in bytes
1105  *                            valid values are between 100 and 400 bytes
1106  *
1107  *
1108  * Return value             : 0 if sucessful
1109  *                           -1 if error happens
1110  */
1111 
WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct * ISAC_main_inst,int16_t maxPayloadBytes)1112 int16_t WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
1113                                         int16_t maxPayloadBytes)
1114 {
1115   ISACFIX_SubStruct *ISAC_inst;
1116 
1117   /* typecast pointer to real structure */
1118   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1119 
1120   if((maxPayloadBytes < 100) || (maxPayloadBytes > 400))
1121   {
1122     /* maxPayloadBytes is out of valid range */
1123     return -1;
1124   }
1125   else
1126   {
1127     /* Set new absolute max, which will not change unless this function
1128        is called again with a new value */
1129     ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes;
1130 
1131     /* Set new maximum values for 30 and 60 msec packets */
1132     if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) {
1133       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes;
1134     } else {
1135       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes;
1136     }
1137 
1138     if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) {
1139       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes;
1140     } else {
1141       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1);
1142     }
1143   }
1144   return 0;
1145 }
1146 
1147 
1148 /****************************************************************************
1149  * WebRtcIsacfix_SetMaxRate(...)
1150  *
1151  * This function sets the maximum rate which the codec may not exceed for a
1152  * singel packet. The maximum rate is set in bits per second.
1153  * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
1154  * per 30 msec).
1155  * It is possible to set a maximum rate between 32000 and 53400 bits per second.
1156  *
1157  * The rate limit is valid until next time the function is called.
1158  *
1159  * NOTE! Packet size will never go above the value set if calling
1160  * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
1161  *
1162  * Input:
1163  *      - ISAC_main_inst    : iSAC instance
1164  *      - maxRateInBytes    : maximum rate in bits per second,
1165  *                            valid values are 32000 to 53400 bits
1166  *
1167  * Return value             : 0 if sucessful
1168  *                           -1 if error happens
1169  */
1170 
WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct * ISAC_main_inst,int32_t maxRate)1171 int16_t WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
1172                                  int32_t maxRate)
1173 {
1174   ISACFIX_SubStruct *ISAC_inst;
1175   int16_t maxRateInBytes;
1176 
1177   /* typecast pointer to real structure */
1178   ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1179 
1180   if((maxRate < 32000) || (maxRate > 53400))
1181   {
1182     /* maxRate is out of valid range */
1183     return -1;
1184   }
1185   else
1186   {
1187     /* Calculate maximum number of bytes per 30 msec packets for the given
1188        maximum rate. Multiply with 30/1000 to get number of bits per 30 msec,
1189        divide by 8 to get number of bytes per 30 msec:
1190        maxRateInBytes = floor((maxRate * 30/1000) / 8); */
1191     maxRateInBytes = (int16_t)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) );
1192 
1193     /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */
1194     ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes;
1195 
1196     /* For 30 msec packets: if the new limit is below the maximum
1197        payload size, set a new limit */
1198     if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1199       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes;
1200     } else {
1201       ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1202     }
1203 
1204     /* For 60 msec packets: if the new limit (times 2) is below the
1205        maximum payload size, set a new limit */
1206     if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1207       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1);
1208     } else {
1209       ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1210     }
1211   }
1212 
1213   return 0;
1214 }
1215 
1216 
1217 
1218 /****************************************************************************
1219  * WebRtcIsacfix_version(...)
1220  *
1221  * This function returns the version number.
1222  *
1223  * Output:
1224  *      - version  : Pointer to character string
1225  *
1226  */
1227 
WebRtcIsacfix_version(char * version)1228 void WebRtcIsacfix_version(char *version)
1229 {
1230   strcpy(version, "3.6.0");
1231 }
1232