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