2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
14 * This C file contains the functions for the ISAC API
18 #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
23 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/bandwidth_estimator.h"
24 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/codec.h"
25 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/entropy_coding.h"
26 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h"
27 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
28 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/structs.h"
29 #include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
31 // Declare function pointers.
32 FilterMaLoopFix WebRtcIsacfix_FilterMaLoopFix;
33 Spec2Time WebRtcIsacfix_Spec2Time;
34 Time2Spec WebRtcIsacfix_Time2Spec;
35 MatrixProduct1 WebRtcIsacfix_MatrixProduct1;
36 MatrixProduct2 WebRtcIsacfix_MatrixProduct2;
38 /**************************************************************************
39 * WebRtcIsacfix_AssignSize(...)
41 * Functions used when malloc is not allowed
42 * Returns number of bytes needed to allocate for iSAC struct.
46 int16_t WebRtcIsacfix_AssignSize(int *sizeinbytes) {
47 *sizeinbytes=sizeof(ISACFIX_SubStruct)*2/sizeof(int16_t);
51 /***************************************************************************
52 * WebRtcIsacfix_Assign(...)
54 * Functions used when malloc is not allowed
55 * Place struct at given address
57 * If successful, Return 0, else Return -1
60 int16_t WebRtcIsacfix_Assign(ISACFIX_MainStruct **inst, void *ISACFIX_inst_Addr) {
61 if (ISACFIX_inst_Addr!=NULL) {
62 *inst = (ISACFIX_MainStruct*)ISACFIX_inst_Addr;
63 (*(ISACFIX_SubStruct**)inst)->errorcode = 0;
64 (*(ISACFIX_SubStruct**)inst)->initflag = 0;
65 (*(ISACFIX_SubStruct**)inst)->ISACenc_obj.SaveEnc_ptr = NULL;
73 #ifndef ISACFIX_NO_DYNAMIC_MEM
75 /****************************************************************************
76 * WebRtcIsacfix_Create(...)
78 * This function creates a ISAC instance, which will contain the state
79 * information for one coding/decoding channel.
82 * - *ISAC_main_inst : a pointer to the coder instance.
84 * Return value : 0 - Ok
88 int16_t WebRtcIsacfix_Create(ISACFIX_MainStruct **ISAC_main_inst)
90 ISACFIX_SubStruct *tempo;
91 tempo = malloc(1 * sizeof(ISACFIX_SubStruct));
92 *ISAC_main_inst = (ISACFIX_MainStruct *)tempo;
93 if (*ISAC_main_inst!=NULL) {
94 (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0;
95 (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0;
96 (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL;
105 /****************************************************************************
106 * WebRtcIsacfix_CreateInternal(...)
108 * This function creates the memory that is used to store data in the encoder
111 * - *ISAC_main_inst : a pointer to the coder instance.
113 * Return value : 0 - Ok
117 int16_t WebRtcIsacfix_CreateInternal(ISACFIX_MainStruct *ISAC_main_inst)
119 ISACFIX_SubStruct *ISAC_inst;
121 /* typecast pointer to real structure */
122 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
124 /* Allocate memory for storing encoder data */
125 ISAC_inst->ISACenc_obj.SaveEnc_ptr = malloc(1 * sizeof(ISAC_SaveEncData_t));
127 if (ISAC_inst->ISACenc_obj.SaveEnc_ptr!=NULL) {
139 /****************************************************************************
140 * WebRtcIsacfix_Free(...)
142 * This function frees the ISAC instance created at the beginning.
145 * - ISAC_main_inst : a ISAC instance.
147 * Return value : 0 - Ok
151 int16_t WebRtcIsacfix_Free(ISACFIX_MainStruct *ISAC_main_inst)
153 free(ISAC_main_inst);
157 /****************************************************************************
158 * WebRtcIsacfix_FreeInternal(...)
160 * This function frees the internal memory for storing encoder data.
163 * - ISAC_main_inst : a ISAC instance.
165 * Return value : 0 - Ok
169 int16_t WebRtcIsacfix_FreeInternal(ISACFIX_MainStruct *ISAC_main_inst)
171 ISACFIX_SubStruct *ISAC_inst;
173 /* typecast pointer to real structure */
174 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
177 free(ISAC_inst->ISACenc_obj.SaveEnc_ptr);
182 /****************************************************************************
183 * WebRtcIsacfix_InitNeon(...)
185 * This function initializes function pointers for ARM Neon platform.
188 #if (defined WEBRTC_DETECT_ARM_NEON || defined WEBRTC_ARCH_ARM_NEON)
189 static void WebRtcIsacfix_InitNeon(void) {
190 WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrNeon;
191 WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopNeon;
192 WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeNeon;
193 WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecNeon;
194 WebRtcIsacfix_CalculateResidualEnergy =
195 WebRtcIsacfix_CalculateResidualEnergyNeon;
196 WebRtcIsacfix_AllpassFilter2FixDec16 =
197 WebRtcIsacfix_AllpassFilter2FixDec16Neon;
198 WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1Neon;
199 WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2Neon;
203 /****************************************************************************
204 * WebRtcIsacfix_InitMIPS(...)
206 * This function initializes function pointers for MIPS platform.
209 #if defined(MIPS32_LE)
210 static void WebRtcIsacfix_InitMIPS(void) {
211 WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrMIPS;
212 WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopMIPS;
213 WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeMIPS;
214 WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecMIPS;
215 WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1MIPS;
216 WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2MIPS;
217 #if defined(MIPS_DSP_R1_LE)
218 WebRtcIsacfix_AllpassFilter2FixDec16 =
219 WebRtcIsacfix_AllpassFilter2FixDec16MIPS;
220 WebRtcIsacfix_HighpassFilterFixDec32 =
221 WebRtcIsacfix_HighpassFilterFixDec32MIPS;
223 #if defined(MIPS_DSP_R2_LE)
224 WebRtcIsacfix_CalculateResidualEnergy =
225 WebRtcIsacfix_CalculateResidualEnergyMIPS;
230 /****************************************************************************
231 * WebRtcIsacfix_EncoderInit(...)
233 * This function initializes a ISAC instance prior to the encoder calls.
236 * - ISAC_main_inst : ISAC instance.
237 * - CodingMode : 0 -> Bit rate and frame length are automatically
238 * adjusted to available bandwidth on
239 * transmission channel.
240 * 1 -> User sets a frame length and a target bit
241 * rate which is taken as the maximum short-term
244 * Return value : 0 - Ok
248 int16_t WebRtcIsacfix_EncoderInit(ISACFIX_MainStruct *ISAC_main_inst,
253 ISACFIX_SubStruct *ISAC_inst;
256 /* typecast pointer to rela structure */
257 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
259 /* flag encoder init */
260 ISAC_inst->initflag |= 2;
264 ISAC_inst->ISACenc_obj.new_framelength = INITIAL_FRAMESAMPLES;
265 else if (CodingMode == 1)
266 /* Instantaneous mode */
267 ISAC_inst->ISACenc_obj.new_framelength = 480; /* default for I-mode */
269 ISAC_inst->errorcode = ISAC_DISALLOWED_CODING_MODE;
273 ISAC_inst->CodingMode = CodingMode;
275 WebRtcIsacfix_InitMaskingEnc(&ISAC_inst->ISACenc_obj.maskfiltstr_obj);
276 WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACenc_obj.prefiltbankstr_obj);
277 WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACenc_obj.pitchfiltstr_obj);
278 WebRtcIsacfix_InitPitchAnalysis(&ISAC_inst->ISACenc_obj.pitchanalysisstr_obj);
281 WebRtcIsacfix_InitBandwidthEstimator(&ISAC_inst->bwestimator_obj);
282 WebRtcIsacfix_InitRateModel(&ISAC_inst->ISACenc_obj.rate_data_obj);
285 ISAC_inst->ISACenc_obj.buffer_index = 0;
286 ISAC_inst->ISACenc_obj.frame_nb = 0;
287 ISAC_inst->ISACenc_obj.BottleNeck = 32000; /* default for I-mode */
288 ISAC_inst->ISACenc_obj.MaxDelay = 10; /* default for I-mode */
289 ISAC_inst->ISACenc_obj.current_framesamples = 0;
290 ISAC_inst->ISACenc_obj.s2nr = 0;
291 ISAC_inst->ISACenc_obj.MaxBits = 0;
292 ISAC_inst->ISACenc_obj.bitstr_seed = 4447;
293 ISAC_inst->ISACenc_obj.payloadLimitBytes30 = STREAM_MAXW16_30MS << 1;
294 ISAC_inst->ISACenc_obj.payloadLimitBytes60 = STREAM_MAXW16_60MS << 1;
295 ISAC_inst->ISACenc_obj.maxPayloadBytes = STREAM_MAXW16_60MS << 1;
296 ISAC_inst->ISACenc_obj.maxRateInBytes = STREAM_MAXW16_30MS << 1;
297 ISAC_inst->ISACenc_obj.enforceFrameSize = 0;
299 /* Init the bistream data area to zero */
300 for (k=0; k<STREAM_MAXW16_60MS; k++){
301 ISAC_inst->ISACenc_obj.bitstr_obj.stream[k] = 0;
304 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
305 WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACenc_obj.interpolatorstr_obj);
308 // Initiaze function pointers.
309 WebRtcIsacfix_AutocorrFix = WebRtcIsacfix_AutocorrC;
310 WebRtcIsacfix_FilterMaLoopFix = WebRtcIsacfix_FilterMaLoopC;
311 WebRtcIsacfix_CalculateResidualEnergy =
312 WebRtcIsacfix_CalculateResidualEnergyC;
313 WebRtcIsacfix_AllpassFilter2FixDec16 = WebRtcIsacfix_AllpassFilter2FixDec16C;
314 WebRtcIsacfix_HighpassFilterFixDec32 = WebRtcIsacfix_HighpassFilterFixDec32C;
315 WebRtcIsacfix_Time2Spec = WebRtcIsacfix_Time2SpecC;
316 WebRtcIsacfix_Spec2Time = WebRtcIsacfix_Spec2TimeC;
317 WebRtcIsacfix_MatrixProduct1 = WebRtcIsacfix_MatrixProduct1C;
318 WebRtcIsacfix_MatrixProduct2 = WebRtcIsacfix_MatrixProduct2C;
320 #ifdef WEBRTC_DETECT_ARM_NEON
321 if ((WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON) != 0) {
322 WebRtcIsacfix_InitNeon();
324 #elif defined(WEBRTC_ARCH_ARM_NEON)
325 WebRtcIsacfix_InitNeon();
328 #if defined(MIPS32_LE)
329 WebRtcIsacfix_InitMIPS();
335 /****************************************************************************
336 * WebRtcIsacfix_Encode(...)
338 * This function encodes 10ms frame(s) and inserts it into a package.
339 * Input speech length has to be 160 samples (10ms). The encoder buffers those
340 * 10ms frames until it reaches the chosen Framesize (480 or 960 samples
341 * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
344 * - ISAC_main_inst : ISAC instance.
345 * - speechIn : input speech vector.
348 * - encoded : the encoded data vector
351 * : >0 - Length (in bytes) of coded data
352 * : 0 - The buffer didn't reach the chosen framesize
353 * so it keeps buffering speech samples.
357 int16_t WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
358 const int16_t *speechIn,
361 ISACFIX_SubStruct *ISAC_inst;
362 int16_t stream_len, stream_len_even;
363 #ifndef WEBRTC_ARCH_BIG_ENDIAN
367 /* typecast pointer to rela structure */
368 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
371 /* check if encoder initiated */
372 if ((ISAC_inst->initflag & 2) != 2) {
373 ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
377 stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechIn,
378 &ISAC_inst->ISACenc_obj,
379 &ISAC_inst->bwestimator_obj,
380 ISAC_inst->CodingMode);
382 ISAC_inst->errorcode = - stream_len;
386 /* One would think that only even stream lengths would make sense here. We do
387 in fact observe odd lengths, however, and in those cases we copy an extra
389 stream_len_even = stream_len % 2 == 0 ? stream_len : stream_len + 1;
391 #ifndef WEBRTC_ARCH_BIG_ENDIAN
392 /* The encoded data vector is supposesd to be big-endian, but our internal
393 representation is little-endian. So byteswap. */
394 for (k = 0; k < stream_len_even / 2; ++k) {
395 uint16_t s = ISAC_inst->ISACenc_obj.bitstr_obj.stream[k];
396 /* In big-endian, we have... */
397 encoded[2 * k] = s >> 8; /* ...most significant byte at low address... */
398 encoded[2 * k + 1] = s; /* ...least significant byte at high address. */
401 /* The encoded data vector and our internal representation are both
403 memcpy(encoded, ISAC_inst->ISACenc_obj.bitstr_obj.stream, stream_len_even);
415 /****************************************************************************
416 * WebRtcIsacfix_EncodeNb(...)
418 * This function encodes 10ms narrow band (8 kHz sampling) frame(s) and inserts
419 * it into a package. Input speech length has to be 80 samples (10ms). The encoder
420 * interpolates into wide-band (16 kHz sampling) buffers those
421 * 10ms frames until it reaches the chosen Framesize (480 or 960 wide-band samples
422 * corresponding to 30 or 60 ms frames), and then proceeds to the encoding.
424 * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
427 * - ISAC_main_inst : ISAC instance.
428 * - speechIn : input speech vector.
431 * - encoded : the encoded data vector
434 * : >0 - Length (in bytes) of coded data
435 * : 0 - The buffer didn't reach the chosen framesize
436 * so it keeps buffering speech samples.
439 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
440 int16_t WebRtcIsacfix_EncodeNb(ISACFIX_MainStruct *ISAC_main_inst,
441 const int16_t *speechIn,
444 ISACFIX_SubStruct *ISAC_inst;
446 int16_t speechInWB[FRAMESAMPLES_10ms];
447 int16_t Vector_Word16_1[FRAMESAMPLES_10ms/2];
448 int16_t Vector_Word16_2[FRAMESAMPLES_10ms/2];
453 /* typecast pointer to rela structure */
454 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
457 /* check if encoder initiated */
458 if ((ISAC_inst->initflag & 2) != 2) {
459 ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
464 /* Oversample to WB */
466 /* Form polyphase signals, and compensate for DC offset */
467 for (k=0;k<FRAMESAMPLES_10ms/2;k++) {
468 Vector_Word16_1[k] = speechIn[k] + 1;
469 Vector_Word16_2[k] = speechIn[k];
471 WebRtcIsacfix_FilterAndCombine2(Vector_Word16_1, Vector_Word16_2, speechInWB, &ISAC_inst->ISACenc_obj.interpolatorstr_obj, FRAMESAMPLES_10ms);
474 /* Encode WB signal */
475 stream_len = WebRtcIsacfix_EncodeImpl((int16_t*)speechInWB,
476 &ISAC_inst->ISACenc_obj,
477 &ISAC_inst->bwestimator_obj,
478 ISAC_inst->CodingMode);
480 ISAC_inst->errorcode = - stream_len;
485 /* convert from bytes to int16_t */
486 #ifndef WEBRTC_ARCH_BIG_ENDIAN
487 for (k=0;k<(stream_len+1)>>1;k++) {
488 encoded[k] = (int16_t)(((uint16_t)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8)
489 | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
493 WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
500 #endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
503 /****************************************************************************
504 * WebRtcIsacfix_GetNewBitStream(...)
506 * This function returns encoded data, with the recieved bwe-index in the
507 * stream. It should always return a complete packet, i.e. only called once
508 * even for 60 msec frames
511 * - ISAC_main_inst : ISAC instance.
512 * - bweIndex : index of bandwidth estimate to put in new bitstream
515 * - encoded : the encoded data vector
518 * : >0 - Length (in bytes) of coded data
522 int16_t WebRtcIsacfix_GetNewBitStream(ISACFIX_MainStruct *ISAC_main_inst,
527 ISACFIX_SubStruct *ISAC_inst;
529 #ifndef WEBRTC_ARCH_BIG_ENDIAN
533 /* typecast pointer to rela structure */
534 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
537 /* check if encoder initiated */
538 if ((ISAC_inst->initflag & 2) != 2) {
539 ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
543 stream_len = WebRtcIsacfix_EncodeStoredData(&ISAC_inst->ISACenc_obj,
547 ISAC_inst->errorcode = - stream_len;
551 #ifndef WEBRTC_ARCH_BIG_ENDIAN
552 for (k=0;k<(stream_len+1)>>1;k++) {
553 encoded[k] = (int16_t)( ( (uint16_t)(ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] >> 8 )
554 | (((ISAC_inst->ISACenc_obj.bitstr_obj).stream[k] & 0x00FF) << 8));
558 WEBRTC_SPL_MEMCPY_W16(encoded, (ISAC_inst->ISACenc_obj.bitstr_obj).stream, (stream_len + 1)>>1);
567 /****************************************************************************
568 * WebRtcIsacfix_DecoderInit(...)
570 * This function initializes a ISAC instance prior to the decoder calls.
573 * - ISAC_main_inst : ISAC instance.
580 int16_t WebRtcIsacfix_DecoderInit(ISACFIX_MainStruct *ISAC_main_inst)
582 ISACFIX_SubStruct *ISAC_inst;
584 /* typecast pointer to real structure */
585 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
587 /* flag decoder init */
588 ISAC_inst->initflag |= 1;
590 WebRtcIsacfix_InitMaskingDec(&ISAC_inst->ISACdec_obj.maskfiltstr_obj);
591 WebRtcIsacfix_InitPostFilterbank(&ISAC_inst->ISACdec_obj.postfiltbankstr_obj);
592 WebRtcIsacfix_InitPitchFilter(&ISAC_inst->ISACdec_obj.pitchfiltstr_obj);
595 WebRtcIsacfix_InitPlc( &ISAC_inst->ISACdec_obj.plcstr_obj );
598 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
599 WebRtcIsacfix_InitPreFilterbank(&ISAC_inst->ISACdec_obj.decimatorstr_obj);
606 /****************************************************************************
607 * WebRtcIsacfix_UpdateBwEstimate1(...)
609 * This function updates the estimate of the bandwidth.
612 * - ISAC_main_inst : ISAC instance.
613 * - encoded : encoded ISAC frame(s).
614 * - packet_size : size of the packet.
615 * - rtp_seq_number : the RTP number of the packet.
616 * - arr_ts : the arrival time of the packet (from NetEq)
619 * Return value : 0 - Ok
623 int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
624 const uint16_t *encoded,
626 uint16_t rtp_seq_number,
629 ISACFIX_SubStruct *ISAC_inst;
630 Bitstr_dec streamdata;
631 #ifndef WEBRTC_ARCH_BIG_ENDIAN
636 /* typecast pointer to real structure */
637 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
639 /* Sanity check of packet length */
640 if (packet_size <= 0) {
641 /* return error code if the packet length is null or less */
642 ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
644 } else if (packet_size > (STREAM_MAXW16<<1)) {
645 /* return error code if length of stream is too long */
646 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
650 /* check if decoder initiated */
651 if ((ISAC_inst->initflag & 1) != 1) {
652 ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
656 streamdata.W_upper = 0xFFFFFFFF;
657 streamdata.streamval = 0;
658 streamdata.stream_index = 0;
661 #ifndef WEBRTC_ARCH_BIG_ENDIAN
662 for (k=0; k<5; k++) {
663 streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
666 memcpy(streamdata.stream, encoded, 5);
669 err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
679 /* return error code if something went wrong */
680 ISAC_inst->errorcode = -err;
688 /****************************************************************************
689 * WebRtcIsacfix_UpdateBwEstimate(...)
691 * This function updates the estimate of the bandwidth.
694 * - ISAC_main_inst : ISAC instance.
695 * - encoded : encoded ISAC frame(s).
696 * - packet_size : size of the packet.
697 * - rtp_seq_number : the RTP number of the packet.
698 * - send_ts : Send Time Stamp from RTP header
699 * - arr_ts : the arrival time of the packet (from NetEq)
702 * Return value : 0 - Ok
706 int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
707 const uint16_t *encoded,
709 uint16_t rtp_seq_number,
713 ISACFIX_SubStruct *ISAC_inst;
714 Bitstr_dec streamdata;
715 #ifndef WEBRTC_ARCH_BIG_ENDIAN
720 /* typecast pointer to real structure */
721 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
723 /* Sanity check of packet length */
724 if (packet_size <= 0) {
725 /* return error code if the packet length is null or less */
726 ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
728 } else if (packet_size > (STREAM_MAXW16<<1)) {
729 /* return error code if length of stream is too long */
730 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
734 /* check if decoder initiated */
735 if ((ISAC_inst->initflag & 1) != 1) {
736 ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
740 streamdata.W_upper = 0xFFFFFFFF;
741 streamdata.streamval = 0;
742 streamdata.stream_index = 0;
745 #ifndef WEBRTC_ARCH_BIG_ENDIAN
746 for (k=0; k<5; k++) {
747 streamdata.stream[k] = (uint16_t) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
750 memcpy(streamdata.stream, encoded, 5);
753 err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
762 /* return error code if something went wrong */
763 ISAC_inst->errorcode = -err;
771 /****************************************************************************
772 * WebRtcIsacfix_Decode(...)
774 * This function decodes a ISAC frame. Output speech length
775 * will be a multiple of 480 samples: 480 or 960 samples,
776 * depending on the framesize (30 or 60 ms).
779 * - ISAC_main_inst : ISAC instance.
780 * - encoded : encoded ISAC frame(s)
781 * - len : bytes in encoded vector
784 * - decoded : The decoded vector
786 * Return value : >0 - number of samples in decoded vector
791 int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
792 const uint16_t *encoded,
797 ISACFIX_SubStruct *ISAC_inst;
798 /* number of samples (480 or 960), output from decoder */
799 /* that were actually used in the encoder/decoder (determined on the fly) */
800 int16_t number_of_samples;
801 #ifndef WEBRTC_ARCH_BIG_ENDIAN
806 /* typecast pointer to real structure */
807 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
809 /* check if decoder initiated */
810 if ((ISAC_inst->initflag & 1) != 1) {
811 ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
815 /* Sanity check of packet length */
817 /* return error code if the packet length is null or less */
818 ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
820 } else if (len > (STREAM_MAXW16<<1)) {
821 /* return error code if length of stream is too long */
822 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
826 ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1;
828 /* convert bitstream from int16_t to bytes */
829 #ifndef WEBRTC_ARCH_BIG_ENDIAN
830 for (k=0; k<(len>>1); k++) {
831 (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
834 (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8);
837 /* added for NetEq purposes (VAD/DTX related) */
840 declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples);
843 /* Some error inside the decoder */
844 ISAC_inst->errorcode = -declen;
845 memset(decoded, 0, sizeof(int16_t) * MAX_FRAMESAMPLES);
851 if (declen & 0x0001) {
852 if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) {
853 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
854 memset(decoded, 0, sizeof(int16_t) * number_of_samples);
858 if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) {
859 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
860 memset(decoded, 0, sizeof(int16_t) * number_of_samples);
865 return number_of_samples;
872 /****************************************************************************
873 * WebRtcIsacfix_DecodeNb(...)
875 * This function decodes a ISAC frame in narrow-band (8 kHz sampling).
876 * Output speech length will be a multiple of 240 samples: 240 or 480 samples,
877 * depending on the framesize (30 or 60 ms).
879 * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
882 * - ISAC_main_inst : ISAC instance.
883 * - encoded : encoded ISAC frame(s)
884 * - len : bytes in encoded vector
887 * - decoded : The decoded vector
889 * Return value : >0 - number of samples in decoded vector
893 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
894 int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
895 const uint16_t *encoded,
900 ISACFIX_SubStruct *ISAC_inst;
901 /* twice the number of samples (480 or 960), output from decoder */
902 /* that were actually used in the encoder/decoder (determined on the fly) */
903 int16_t number_of_samples;
904 #ifndef WEBRTC_ARCH_BIG_ENDIAN
908 int16_t dummy[FRAMESAMPLES/2];
911 /* typecast pointer to real structure */
912 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
914 /* check if decoder initiated */
915 if ((ISAC_inst->initflag & 1) != 1) {
916 ISAC_inst->errorcode = ISAC_DECODER_NOT_INITIATED;
921 { /* return error code if the packet length is null */
923 ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
927 ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1;
929 /* convert bitstream from int16_t to bytes */
930 #ifndef WEBRTC_ARCH_BIG_ENDIAN
931 for (k=0; k<(len>>1); k++) {
932 (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
935 (ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8);
938 /* added for NetEq purposes (VAD/DTX related) */
941 declen = WebRtcIsacfix_DecodeImpl(decoded,&ISAC_inst->ISACdec_obj, &number_of_samples);
944 /* Some error inside the decoder */
945 ISAC_inst->errorcode = -declen;
946 memset(decoded, 0, sizeof(int16_t) * FRAMESAMPLES);
952 if (declen & 0x0001) {
953 if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) & 0x00FF) ) {
954 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
955 memset(decoded, 0, sizeof(int16_t) * number_of_samples);
959 if (len != declen && len != declen + (((ISAC_inst->ISACdec_obj.bitstr_obj).stream[declen>>1]) >> 8) ) {
960 ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
961 memset(decoded, 0, sizeof(int16_t) * number_of_samples);
966 WebRtcIsacfix_SplitAndFilter2(decoded, decoded, dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
968 if (number_of_samples>FRAMESAMPLES) {
969 WebRtcIsacfix_SplitAndFilter2(decoded + FRAMESAMPLES, decoded + FRAMESAMPLES/2,
970 dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
973 return number_of_samples/2;
975 #endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
978 /****************************************************************************
979 * WebRtcIsacfix_DecodePlcNb(...)
981 * This function conducts PLC for ISAC frame(s) in narrow-band (8kHz sampling).
982 * Output speech length will be "240*noOfLostFrames" samples
983 * that is equevalent of "30*noOfLostFrames" millisecond.
985 * The function is enabled if WEBRTC_ISAC_FIX_NB_CALLS_ENABLED is defined
988 * - ISAC_main_inst : ISAC instance.
989 * - noOfLostFrames : Number of PLC frames (240 sample=30ms) to produce
992 * - decoded : The decoded vector
994 * Return value : >0 - number of samples in decoded PLC vector
998 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
999 int16_t WebRtcIsacfix_DecodePlcNb(ISACFIX_MainStruct *ISAC_main_inst,
1001 int16_t noOfLostFrames )
1003 int16_t no_of_samples, declen, k, ok;
1004 int16_t outframeNB[FRAMESAMPLES];
1005 int16_t outframeWB[FRAMESAMPLES];
1006 int16_t dummy[FRAMESAMPLES/2];
1009 ISACFIX_SubStruct *ISAC_inst;
1010 /* typecast pointer to real structure */
1011 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1013 /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
1014 if (noOfLostFrames > 2){
1020 while( noOfLostFrames > 0 )
1022 ok = WebRtcIsacfix_DecodePlcImpl( outframeWB, &ISAC_inst->ISACdec_obj, &no_of_samples );
1026 WebRtcIsacfix_SplitAndFilter2(outframeWB, &(outframeNB[k*240]), dummy, &ISAC_inst->ISACdec_obj.decimatorstr_obj);
1028 declen += no_of_samples;
1035 for (k=0;k<declen;k++) {
1036 decoded[k] = outframeNB[k];
1041 #endif /* WEBRTC_ISAC_FIX_NB_CALLS_ENABLED */
1046 /****************************************************************************
1047 * WebRtcIsacfix_DecodePlc(...)
1049 * This function conducts PLC for ISAC frame(s) in wide-band (16kHz sampling).
1050 * Output speech length will be "480*noOfLostFrames" samples
1051 * that is equevalent of "30*noOfLostFrames" millisecond.
1054 * - ISAC_main_inst : ISAC instance.
1055 * - noOfLostFrames : Number of PLC frames (480sample = 30ms)
1059 * - decoded : The decoded vector
1061 * Return value : >0 - number of samples in decoded PLC vector
1065 int16_t WebRtcIsacfix_DecodePlc(ISACFIX_MainStruct *ISAC_main_inst,
1067 int16_t noOfLostFrames)
1070 int16_t no_of_samples, declen, k, ok;
1071 int16_t outframe16[MAX_FRAMESAMPLES];
1073 ISACFIX_SubStruct *ISAC_inst;
1074 /* typecast pointer to real structure */
1075 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1077 /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */
1078 if (noOfLostFrames > 2) {
1083 while( noOfLostFrames > 0 )
1085 ok = WebRtcIsacfix_DecodePlcImpl( &(outframe16[k*480]), &ISAC_inst->ISACdec_obj, &no_of_samples );
1088 declen += no_of_samples;
1093 for (k=0;k<declen;k++) {
1094 decoded[k] = outframe16[k];
1101 /****************************************************************************
1102 * WebRtcIsacfix_Control(...)
1104 * This function sets the limit on the short-term average bit rate and the
1105 * frame length. Should be used only in Instantaneous mode.
1108 * - ISAC_main_inst : ISAC instance.
1109 * - rate : limit on the short-term average bit rate,
1110 * in bits/second (between 10000 and 32000)
1111 * - framesize : number of milliseconds per frame (30 or 60)
1113 * Return value : 0 - ok
1117 int16_t WebRtcIsacfix_Control(ISACFIX_MainStruct *ISAC_main_inst,
1121 ISACFIX_SubStruct *ISAC_inst;
1122 /* typecast pointer to real structure */
1123 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1125 if (ISAC_inst->CodingMode == 0)
1127 /* in adaptive mode */
1128 ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1133 if (rate >= 10000 && rate <= 32000)
1134 ISAC_inst->ISACenc_obj.BottleNeck = rate;
1136 ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1142 if (framesize == 30 || framesize == 60)
1143 ISAC_inst->ISACenc_obj.new_framelength = (FS/1000) * framesize;
1145 ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1153 /****************************************************************************
1154 * WebRtcIsacfix_ControlBwe(...)
1156 * This function sets the initial values of bottleneck and frame-size if
1157 * iSAC is used in channel-adaptive mode. Through this API, users can
1158 * enforce a frame-size for all values of bottleneck. Then iSAC will not
1159 * automatically change the frame-size.
1163 * - ISAC_main_inst : ISAC instance.
1164 * - rateBPS : initial value of bottleneck in bits/second
1165 * 10000 <= rateBPS <= 32000 is accepted
1166 * For default bottleneck set rateBPS = 0
1167 * - frameSizeMs : number of milliseconds per frame (30 or 60)
1168 * - enforceFrameSize : 1 to enforce the given frame-size through out
1169 * the adaptation process, 0 to let iSAC change
1170 * the frame-size if required.
1172 * Return value : 0 - ok
1176 int16_t WebRtcIsacfix_ControlBwe(ISACFIX_MainStruct *ISAC_main_inst,
1178 int16_t frameSizeMs,
1179 int16_t enforceFrameSize)
1181 ISACFIX_SubStruct *ISAC_inst;
1182 /* Typecast pointer to real structure */
1183 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1185 /* check if encoder initiated */
1186 if ((ISAC_inst->initflag & 2) != 2) {
1187 ISAC_inst->errorcode = ISAC_ENCODER_NOT_INITIATED;
1191 /* Check that we are in channel-adaptive mode, otherwise, return -1 */
1192 if (ISAC_inst->CodingMode != 0) {
1193 ISAC_inst->errorcode = ISAC_MODE_MISMATCH;
1197 /* Set struct variable if enforceFrameSize is set. ISAC will then keep the */
1198 /* chosen frame size. */
1199 ISAC_inst->ISACenc_obj.enforceFrameSize = (enforceFrameSize != 0)? 1:0;
1201 /* Set initial rate, if value between 10000 and 32000, */
1202 /* if rateBPS is 0, keep the default initial bottleneck value (15000) */
1203 if ((rateBPS >= 10000) && (rateBPS <= 32000)) {
1204 ISAC_inst->bwestimator_obj.sendBwAvg = (((uint32_t)rateBPS) << 7);
1205 } else if (rateBPS != 0) {
1206 ISAC_inst->errorcode = ISAC_DISALLOWED_BOTTLENECK;
1210 /* Set initial framesize. If enforceFrameSize is set the frame size will not change */
1211 if ((frameSizeMs == 30) || (frameSizeMs == 60)) {
1212 ISAC_inst->ISACenc_obj.new_framelength = (FS/1000) * frameSizeMs;
1214 ISAC_inst->errorcode = ISAC_DISALLOWED_FRAME_LENGTH;
1225 /****************************************************************************
1226 * WebRtcIsacfix_GetDownLinkBwIndex(...)
1228 * This function returns index representing the Bandwidth estimate from
1229 * other side to this side.
1232 * - ISAC_main_inst: iSAC struct
1235 * - rateIndex : Bandwidth estimate to transmit to other side.
1239 int16_t WebRtcIsacfix_GetDownLinkBwIndex(ISACFIX_MainStruct* ISAC_main_inst,
1242 ISACFIX_SubStruct *ISAC_inst;
1244 /* typecast pointer to real structure */
1245 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1247 /* Call function to get Bandwidth Estimate */
1248 *rateIndex = WebRtcIsacfix_GetDownlinkBwIndexImpl(&ISAC_inst->bwestimator_obj);
1254 /****************************************************************************
1255 * WebRtcIsacfix_UpdateUplinkBw(...)
1257 * This function takes an index representing the Bandwidth estimate from
1258 * this side to other side and updates BWE.
1261 * - ISAC_main_inst: iSAC struct
1262 * - rateIndex : Bandwidth estimate from other side.
1266 int16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
1270 ISACFIX_SubStruct *ISAC_inst;
1272 /* typecast pointer to real structure */
1273 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1275 /* Call function to update BWE with received Bandwidth Estimate */
1276 err = WebRtcIsacfix_UpdateUplinkBwRec(&ISAC_inst->bwestimator_obj, rateIndex);
1278 ISAC_inst->errorcode = -err;
1285 /****************************************************************************
1286 * WebRtcIsacfix_ReadFrameLen(...)
1288 * This function returns the length of the frame represented in the packet.
1291 * - encoded : Encoded bitstream
1294 * - frameLength : Length of frame in packet (in samples)
1298 int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded,
1299 int16_t* frameLength)
1301 Bitstr_dec streamdata;
1302 #ifndef WEBRTC_ARCH_BIG_ENDIAN
1307 streamdata.W_upper = 0xFFFFFFFF;
1308 streamdata.streamval = 0;
1309 streamdata.stream_index = 0;
1310 streamdata.full = 1;
1312 #ifndef WEBRTC_ARCH_BIG_ENDIAN
1313 for (k=0; k<5; k++) {
1314 streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
1317 memcpy(streamdata.stream, encoded, 5);
1320 /* decode frame length */
1321 err = WebRtcIsacfix_DecodeFrameLen(&streamdata, frameLength);
1322 if (err<0) // error check
1329 /****************************************************************************
1330 * WebRtcIsacfix_ReadBwIndex(...)
1332 * This function returns the index of the Bandwidth estimate from the bitstream.
1335 * - encoded : Encoded bitstream
1338 * - frameLength : Length of frame in packet (in samples)
1339 * - rateIndex : Bandwidth estimate in bitstream
1343 int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded,
1346 Bitstr_dec streamdata;
1347 #ifndef WEBRTC_ARCH_BIG_ENDIAN
1352 streamdata.W_upper = 0xFFFFFFFF;
1353 streamdata.streamval = 0;
1354 streamdata.stream_index = 0;
1355 streamdata.full = 1;
1357 #ifndef WEBRTC_ARCH_BIG_ENDIAN
1358 for (k=0; k<5; k++) {
1359 streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
1362 memcpy(streamdata.stream, encoded, 5);
1365 /* decode frame length, needed to get to the rateIndex in the bitstream */
1366 err = WebRtcIsacfix_DecodeFrameLen(&streamdata, rateIndex);
1367 if (err<0) // error check
1370 /* decode BW estimation */
1371 err = WebRtcIsacfix_DecodeSendBandwidth(&streamdata, rateIndex);
1372 if (err<0) // error check
1381 /****************************************************************************
1382 * WebRtcIsacfix_GetErrorCode(...)
1384 * This function can be used to check the error code of an iSAC instance. When
1385 * a function returns -1 a error code will be set for that instance. The
1386 * function below extract the code of the last error that occured in the
1387 * specified instance.
1390 * - ISAC_main_inst : ISAC instance
1392 * Return value : Error code
1395 int16_t WebRtcIsacfix_GetErrorCode(ISACFIX_MainStruct *ISAC_main_inst)
1397 ISACFIX_SubStruct *ISAC_inst;
1398 /* typecast pointer to real structure */
1399 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1401 return ISAC_inst->errorcode;
1406 /****************************************************************************
1407 * WebRtcIsacfix_GetUplinkBw(...)
1409 * This function returns the inst quantized iSAC send bitrate
1412 * - ISAC_main_inst : iSAC instance
1414 * Return value : bitrate
1417 int32_t WebRtcIsacfix_GetUplinkBw(ISACFIX_MainStruct *ISAC_main_inst)
1419 ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1420 BwEstimatorstr * bw = (BwEstimatorstr*)&(ISAC_inst->bwestimator_obj);
1422 return (int32_t) WebRtcIsacfix_GetUplinkBandwidth(bw);
1425 /****************************************************************************
1426 * WebRtcIsacfix_GetNewFrameLen(...)
1428 * This function return the next frame length (in samples) of iSAC.
1431 * - ISAC_main_inst : iSAC instance
1433 * Return value : frame lenght in samples
1436 int16_t WebRtcIsacfix_GetNewFrameLen(ISACFIX_MainStruct *ISAC_main_inst)
1438 ISACFIX_SubStruct *ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1439 return ISAC_inst->ISACenc_obj.new_framelength;
1443 /****************************************************************************
1444 * WebRtcIsacfix_SetMaxPayloadSize(...)
1446 * This function sets a limit for the maximum payload size of iSAC. The same
1447 * value is used both for 30 and 60 msec packets.
1448 * The absolute max will be valid until next time the function is called.
1449 * NOTE! This function may override the function WebRtcIsacfix_SetMaxRate()
1452 * - ISAC_main_inst : iSAC instance
1453 * - maxPayloadBytes : maximum size of the payload in bytes
1454 * valid values are between 100 and 400 bytes
1457 * Return value : 0 if sucessful
1458 * -1 if error happens
1461 int16_t WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_MainStruct *ISAC_main_inst,
1462 int16_t maxPayloadBytes)
1464 ISACFIX_SubStruct *ISAC_inst;
1466 /* typecast pointer to real structure */
1467 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1469 if((maxPayloadBytes < 100) || (maxPayloadBytes > 400))
1471 /* maxPayloadBytes is out of valid range */
1476 /* Set new absolute max, which will not change unless this function
1477 is called again with a new value */
1478 ISAC_inst->ISACenc_obj.maxPayloadBytes = maxPayloadBytes;
1480 /* Set new maximum values for 30 and 60 msec packets */
1481 if (maxPayloadBytes < ISAC_inst->ISACenc_obj.maxRateInBytes) {
1482 ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxPayloadBytes;
1484 ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxRateInBytes;
1487 if ( maxPayloadBytes < (ISAC_inst->ISACenc_obj.maxRateInBytes << 1)) {
1488 ISAC_inst->ISACenc_obj.payloadLimitBytes60 = maxPayloadBytes;
1490 ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (ISAC_inst->ISACenc_obj.maxRateInBytes << 1);
1497 /****************************************************************************
1498 * WebRtcIsacfix_SetMaxRate(...)
1500 * This function sets the maximum rate which the codec may not exceed for a
1501 * singel packet. The maximum rate is set in bits per second.
1502 * The codec has an absolute maximum rate of 53400 bits per second (200 bytes
1504 * It is possible to set a maximum rate between 32000 and 53400 bits per second.
1506 * The rate limit is valid until next time the function is called.
1508 * NOTE! Packet size will never go above the value set if calling
1509 * WebRtcIsacfix_SetMaxPayloadSize() (default max packet size is 400 bytes).
1512 * - ISAC_main_inst : iSAC instance
1513 * - maxRateInBytes : maximum rate in bits per second,
1514 * valid values are 32000 to 53400 bits
1516 * Return value : 0 if sucessful
1517 * -1 if error happens
1520 int16_t WebRtcIsacfix_SetMaxRate(ISACFIX_MainStruct *ISAC_main_inst,
1523 ISACFIX_SubStruct *ISAC_inst;
1524 int16_t maxRateInBytes;
1526 /* typecast pointer to real structure */
1527 ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
1529 if((maxRate < 32000) || (maxRate > 53400))
1531 /* maxRate is out of valid range */
1536 /* Calculate maximum number of bytes per 30 msec packets for the given
1537 maximum rate. Multiply with 30/1000 to get number of bits per 30 msec,
1538 divide by 8 to get number of bytes per 30 msec:
1539 maxRateInBytes = floor((maxRate * 30/1000) / 8); */
1540 maxRateInBytes = (int16_t)( WebRtcSpl_DivW32W16ResW16(WEBRTC_SPL_MUL(maxRate, 3), 800) );
1542 /* Store the value for usage in the WebRtcIsacfix_SetMaxPayloadSize-function */
1543 ISAC_inst->ISACenc_obj.maxRateInBytes = maxRateInBytes;
1545 /* For 30 msec packets: if the new limit is below the maximum
1546 payload size, set a new limit */
1547 if (maxRateInBytes < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1548 ISAC_inst->ISACenc_obj.payloadLimitBytes30 = maxRateInBytes;
1550 ISAC_inst->ISACenc_obj.payloadLimitBytes30 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1553 /* For 60 msec packets: if the new limit (times 2) is below the
1554 maximum payload size, set a new limit */
1555 if ( (maxRateInBytes << 1) < ISAC_inst->ISACenc_obj.maxPayloadBytes) {
1556 ISAC_inst->ISACenc_obj.payloadLimitBytes60 = (maxRateInBytes << 1);
1558 ISAC_inst->ISACenc_obj.payloadLimitBytes60 = ISAC_inst->ISACenc_obj.maxPayloadBytes;
1567 /****************************************************************************
1568 * WebRtcIsacfix_version(...)
1570 * This function returns the version number.
1573 * - version : Pointer to character string
1577 void WebRtcIsacfix_version(char *version)
1579 strcpy(version, "3.6.0");