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