From ba108aee21a9d326410cec858cbd5f336a0c0e02 Mon Sep 17 00:00:00 2001 From: "turaj@webrtc.org" Date: Mon, 4 Jun 2012 20:04:58 +0000 Subject: [PATCH] This CL contains some refactoring. Spectrum coding is main place that is affected. Therefore, I have bit-exactness test, test_spectrum_ coding.c, to be sure about the changelist. You can go through the test to be sure the changes are tested. However, I don't intend to commi t the test, as it would be a source of confusion and requires hack to iSAC to be able to run the test. It is basically a one-time test. The part which not covered in this test is where we limit payload for super-wideband bit-stream. I'll add a test for that as well. I kept format changes at minimum in all files except isac.c, which was in bad shape, and coding changes were minimum. I'm planning to uplo ad following patches to this CL where I try to address formatting issues. But I don't intend to change variable names, for the moment. The refactoring is not yet finished, so you would find part of the code which could be cleaned up, especially KLT transforms in entropy_co ding.c Review URL: https://webrtc-codereview.appspot.com/580004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@2359 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../codecs/iSAC/main/source/codec.h | 205 +- .../codecs/iSAC/main/source/decode.c | 197 +- .../codecs/iSAC/main/source/encode.c | 1146 +++--- .../codecs/iSAC/main/source/entropy_coding.c | 1928 ++++------- .../codecs/iSAC/main/source/entropy_coding.h | 232 +- .../codecs/iSAC/main/source/isac.c | 3072 +++++++---------- .../codecs/iSAC/main/source/settings.h | 2 +- 7 files changed, 2666 insertions(+), 4116 deletions(-) diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/codec.h b/src/modules/audio_coding/codecs/iSAC/main/source/codec.h index 6af27ea9e0..0b4d862056 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/codec.h +++ b/src/modules/audio_coding/codecs/iSAC/main/source/codec.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. + * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source @@ -21,57 +21,39 @@ #include "structs.h" -int WebRtcIsac_EstimateBandwidth( - BwEstimatorstr* bwest_str, - Bitstr* streamdata, - WebRtc_Word32 packet_size, - WebRtc_UWord16 rtp_seq_number, - WebRtc_UWord32 send_ts, - WebRtc_UWord32 arr_ts, - enum IsacSamplingRate encoderSampRate, - enum IsacSamplingRate decoderSampRate); -int WebRtcIsac_DecodeLb( - float* signal_out, - ISACLBDecStruct* ISACdec_obj, - WebRtc_Word16* current_framesamples, - WebRtc_Word16 isRCUPayload); +void WebRtcIsac_ResetBitstream(Bitstr* bit_stream); -int WebRtcIsac_DecodeRcuLb( - float* signal_out, - ISACLBDecStruct* ISACdec_obj, - WebRtc_Word16* current_framesamples); +int WebRtcIsac_EstimateBandwidth(BwEstimatorstr* bwest_str, Bitstr* streamdata, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, WebRtc_UWord32 arr_ts, + enum IsacSamplingRate encoderSampRate, + enum IsacSamplingRate decoderSampRate); -int WebRtcIsac_EncodeLb( - float* in, - ISACLBEncStruct* ISACencLB_obj, - WebRtc_Word16 codingMode, - WebRtc_Word16 bottleneckIndex); +int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdec_obj, + WebRtc_Word16* current_framesamples, + WebRtc_Word16 isRCUPayload); -int WebRtcIsac_EncodeStoredDataLb( - const ISAC_SaveEncData_t* ISACSavedEnc_obj, - Bitstr* ISACBitStr_obj, - int BWnumber, - float scale); +int WebRtcIsac_DecodeRcuLb(float* signal_out, ISACLBDecStruct* ISACdec_obj, + WebRtc_Word16* current_framesamples); +int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj, + WebRtc_Word16 codingMode, WebRtc_Word16 + bottleneckIndex); -int WebRtcIsac_EncodeStoredDataUb12( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale); - -int WebRtcIsac_EncodeStoredDataUb16( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale); +int WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t* ISACSavedEnc_obj, + Bitstr* ISACBitStr_obj, int BWnumber, + float scale); +int WebRtcIsac_EncodeStoredDataUb( + const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, Bitstr* bitStream, + WebRtc_Word32 jitterInfo, float scale, enum ISACBandwidth bandwidth); WebRtc_Word16 WebRtcIsac_GetRedPayloadUb( - const ISACUBSaveEncDataStruct* ISACSavedEncObj, - Bitstr* bitStreamObj, - enum ISACBandwidth bandwidth); + const ISACUBSaveEncDataStruct* ISACSavedEncObj, Bitstr* bitStreamObj, + enum ISACBandwidth bandwidth); + /****************************************************************************** * WebRtcIsac_RateAllocation() * Internal function to perform a rate-allocation for upper and lower-band, @@ -90,12 +72,10 @@ WebRtc_Word16 WebRtcIsac_GetRedPayloadUb( * -1 if failed to allocate rates. */ -WebRtc_Word16 -WebRtcIsac_RateAllocation( - WebRtc_Word32 inRateBitPerSec, - double* rateLBBitPerSec, - double* rateUBBitPerSec, - enum ISACBandwidth* bandwidthKHz); +WebRtc_Word16 WebRtcIsac_RateAllocation(WebRtc_Word32 inRateBitPerSec, + double* rateLBBitPerSec, + double* rateUBBitPerSec, + enum ISACBandwidth* bandwidthKHz); /****************************************************************************** @@ -113,10 +93,8 @@ WebRtcIsac_RateAllocation( * Return value : >0 number of decoded bytes. * <0 if an error occurred. */ -int WebRtcIsac_DecodeUb16( - float* signal_out, - ISACUBDecStruct* ISACdec_obj, - WebRtc_Word16 isRCUPayload); +int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdec_obj, + WebRtc_Word16 isRCUPayload); /****************************************************************************** @@ -134,10 +112,8 @@ int WebRtcIsac_DecodeUb16( * Return value : >0 number of decoded bytes. * <0 if an error occurred. */ -int WebRtcIsac_DecodeUb12( - float* signal_out, - ISACUBDecStruct* ISACdec_obj, - WebRtc_Word16 isRCUPayload); +int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdec_obj, + WebRtc_Word16 isRCUPayload); /****************************************************************************** @@ -155,10 +131,8 @@ int WebRtcIsac_DecodeUb12( * Return value : >0 number of encoded bytes. * <0 if an error occurred. */ -int WebRtcIsac_EncodeUb16( - float* in, - ISACUBEncStruct* ISACenc_obj, - WebRtc_Word32 jitterInfo); +int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACenc_obj, + WebRtc_Word32 jitterInfo); /****************************************************************************** @@ -176,117 +150,68 @@ int WebRtcIsac_EncodeUb16( * Return value : >0 number of encoded bytes. * <0 if an error occurred. */ -int WebRtcIsac_EncodeUb12( - float* in, - ISACUBEncStruct* ISACenc_obj, - WebRtc_Word32 jitterInfo); +int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACenc_obj, + WebRtc_Word32 jitterInfo); /************************** initialization functions *************************/ -void WebRtcIsac_InitMasking(MaskFiltstr *maskdata); +void WebRtcIsac_InitMasking(MaskFiltstr* maskdata); -void WebRtcIsac_InitPreFilterbank(PreFiltBankstr *prefiltdata); +void WebRtcIsac_InitPreFilterbank(PreFiltBankstr* prefiltdata); -void WebRtcIsac_InitPostFilterbank(PostFiltBankstr *postfiltdata); +void WebRtcIsac_InitPostFilterbank(PostFiltBankstr* postfiltdata); -void WebRtcIsac_InitPitchFilter(PitchFiltstr *pitchfiltdata); +void WebRtcIsac_InitPitchFilter(PitchFiltstr* pitchfiltdata); -void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct *State); +void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct* State); /**************************** transform functions ****************************/ void WebRtcIsac_InitTransform(); -void WebRtcIsac_Time2Spec(double *inre1, - double *inre2, - WebRtc_Word16 *outre, - WebRtc_Word16 *outim, - FFTstr *fftstr_obj); +void WebRtcIsac_Time2Spec(double* inre1, double* inre2, WebRtc_Word16* outre, + WebRtc_Word16* outim, FFTstr* fftstr_obj); -void WebRtcIsac_Spec2time(double *inre, - double *inim, - double *outre1, - double *outre2, - FFTstr *fftstr_obj); +void WebRtcIsac_Spec2time(double* inre, double* inim, double* outre1, + double* outre2, FFTstr* fftstr_obj); /******************************* filter functions ****************************/ -void WebRtcIsac_AllPoleFilter(double *InOut, - double *Coef, - int lengthInOut, - int orderCoef); +void WebRtcIsac_AllPoleFilter(double* InOut, double* Coef, int lengthInOut, + int orderCoef); -void WebRtcIsac_AllZeroFilter(double *In, - double *Coef, - int lengthInOut, - int orderCoef, - double *Out); +void WebRtcIsac_AllZeroFilter(double* In, double* Coef, int lengthInOut, + int orderCoef, double* Out); -void WebRtcIsac_ZeroPoleFilter(double *In, - double *ZeroCoef, - double *PoleCoef, - int lengthInOut, - int orderCoef, - double *Out); +void WebRtcIsac_ZeroPoleFilter(double* In, double* ZeroCoef, double* PoleCoef, + int lengthInOut, int orderCoef, double* Out); /***************************** filterbank functions **************************/ -void WebRtcIsac_SplitAndFilter(double *in, - double *LP, - double *HP, - double *LP_la, - double *HP_la, - PreFiltBankstr *prefiltdata); +void WebRtcIsac_SplitAndFilterFloat(float* in, float* LP, float* HP, + double* LP_la, double* HP_la, + PreFiltBankstr* prefiltdata); -void WebRtcIsac_FilterAndCombine(double *InLP, - double *InHP, - double *Out, - PostFiltBankstr *postfiltdata); - - - -void WebRtcIsac_SplitAndFilterFloat(float *in, - float *LP, - float *HP, - double *LP_la, - double *HP_la, - PreFiltBankstr *prefiltdata); - - -void WebRtcIsac_FilterAndCombineFloat(float *InLP, - float *InHP, - float *Out, - PostFiltBankstr *postfiltdata); +void WebRtcIsac_FilterAndCombineFloat(float* InLP, float* InHP, float* Out, + PostFiltBankstr* postfiltdata); /************************* normalized lattice filters ************************/ -void WebRtcIsac_NormLatticeFilterMa(int orderCoef, - float *stateF, - float *stateG, - float *lat_in, - double *filtcoeflo, - double *lat_out); +void WebRtcIsac_NormLatticeFilterMa(int orderCoef, float* stateF, float* stateG, + float* lat_in, double* filtcoeflo, + double* lat_out); -void WebRtcIsac_NormLatticeFilterAr(int orderCoef, - float *stateF, - float *stateG, - double *lat_in, - double *lo_filt_coef, - float *lat_out); +void WebRtcIsac_NormLatticeFilterAr(int orderCoef, float* stateF, float* stateG, + double* lat_in, double* lo_filt_coef, + float* lat_out); -void WebRtcIsac_Dir2Lat(double *a, - int orderCoef, - float *sth, - float *cth); +void WebRtcIsac_Dir2Lat(double* a, int orderCoef, float* sth, float* cth); -void WebRtcIsac_AutoCorr(double *r, - const double *x, - int N, - int order); +void WebRtcIsac_AutoCorr(double* r, const double* x, int N, int order); #endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CODEC_H_ */ diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/decode.c b/src/modules/audio_coding/codecs/iSAC/main/source/decode.c index 0c450e90ca..2b06cd08d4 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/decode.c +++ b/src/modules/audio_coding/codecs/iSAC/main/source/decode.c @@ -35,13 +35,9 @@ * function to decode the bitstream * returns the total number of bytes in the stream */ -int -WebRtcIsac_DecodeLb( - float* signal_out, - ISACLBDecStruct* ISACdecLB_obj, - WebRtc_Word16* current_framesamples, - WebRtc_Word16 isRCUPayload) -{ +int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdecLB_obj, + WebRtc_Word16* current_framesamples, + WebRtc_Word16 isRCUPayload) { int k; int len, err; WebRtc_Word16 bandwidthInd; @@ -53,8 +49,8 @@ WebRtcIsac_DecodeLb( double HPw[FRAMESAMPLES_HALF]; double LPw_pf[FRAMESAMPLES_HALF]; - double lo_filt_coef[(ORDERLO+1)*SUBFRAMES]; - double hi_filt_coef[(ORDERHI+1)*SUBFRAMES]; + double lo_filt_coef[(ORDERLO + 1)*SUBFRAMES]; + double hi_filt_coef[(ORDERHI + 1)*SUBFRAMES]; double real_f[FRAMESAMPLES_HALF]; double imag_f[FRAMESAMPLES_HALF]; @@ -68,104 +64,98 @@ WebRtcIsac_DecodeLb( float gain; int frame_nb; /* counter */ - int frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */ - int processed_samples; + int frame_mode; /* 0 30ms, 1 for 60ms */ + /* Processed_samples: 480 (30, 60 ms). Cannot take other values. */ - (ISACdecLB_obj->bitstr_obj).W_upper = 0xFFFFFFFF; - (ISACdecLB_obj->bitstr_obj).streamval = 0; - (ISACdecLB_obj->bitstr_obj).stream_index = 0; + WebRtcIsac_ResetBitstream(&(ISACdecLB_obj->bitstr_obj)); len = 0; - /* decode framelength and BW estimation - not used, + /* Decode framelength and BW estimation - not used, only for stream pointer*/ err = WebRtcIsac_DecodeFrameLen(&ISACdecLB_obj->bitstr_obj, current_framesamples); - if (err < 0) { // error check + if (err < 0) { return err; } - /* frame_mode: 0, or 1 */ - frame_mode = *current_framesamples/MAX_FRAMESAMPLES; - /* processed_samples: either 320 (20ms) or 480 (30, 60 ms) */ - processed_samples = *current_framesamples/(frame_mode+1); + /* Frame_mode: + * 0: indicates 30 ms frame (480 samples) + * 1: indicates 60 ms frame (960 samples) */ + frame_mode = *current_framesamples / MAX_FRAMESAMPLES; err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd); - if (err < 0) { // error check + if (err < 0) { return err; } - /* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames - bundled together (60ms) */ + /* One loop if it's one frame (20 or 30ms), 2 loops if 2 frames + bundled together (60ms). */ for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) { - /* decode & dequantize pitch parameters */ - err = WebRtcIsac_DecodePitchGain(&(ISACdecLB_obj->bitstr_obj), + /* Decode & de-quantize pitch parameters */ + err = WebRtcIsac_DecodePitchGain(&ISACdecLB_obj->bitstr_obj, PitchGains_Q12); - if (err < 0) { // error check + if (err < 0) { return err; } - err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, - PitchGains_Q12, PitchLags); - if (err < 0) { // error check + err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, PitchGains_Q12, + PitchLags); + if (err < 0) { return err; } AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] + - PitchGains_Q12[2] + PitchGains_Q12[3])>>2; + PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2; - /* decode & dequantize FiltCoef */ - err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, - lo_filt_coef,hi_filt_coef); - if (err < 0) { // error check + /* Decode & de-quantize filter coefficients. */ + err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, lo_filt_coef, + hi_filt_coef); + if (err < 0) { return err; } - /* decode & dequantize spectrum */ - len = WebRtcIsac_DecodeSpecLb(&ISACdecLB_obj->bitstr_obj, - real_f, imag_f, AvgPitchGain_Q12); - if (len < 0) { // error check + /* Decode & de-quantize spectrum. */ + len = WebRtcIsac_DecodeSpec(&ISACdecLB_obj->bitstr_obj, AvgPitchGain_Q12, + kIsacLowerBand, real_f, imag_f); + if (len < 0) { return len; } - /* inverse transform */ + /* Inverse transform. */ WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, - &ISACdecLB_obj->fftstr_obj); + &ISACdecLB_obj->fftstr_obj); - /* convert PitchGains back to FLOAT for pitchfilter_post */ + /* Convert PitchGains back to float for pitchfilter_post */ for (k = 0; k < 4; k++) { - PitchGains[k] = ((float)PitchGains_Q12[k])/4096; + PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096; } - - if(isRCUPayload) - { + if (isRCUPayload) { for (k = 0; k < 240; k++) { LPw[k] *= RCU_TRANSCODING_SCALE_INVERSE; HPw[k] *= RCU_TRANSCODING_SCALE_INVERSE; } } - /* inverse pitch filter */ - WebRtcIsac_PitchfilterPost(LPw, LPw_pf, - &ISACdecLB_obj->pitchfiltstr_obj, PitchLags, PitchGains); - /* convert AvgPitchGain back to FLOAT for computation of gain */ - AvgPitchGain = ((float)AvgPitchGain_Q12)/4096; + /* Inverse pitch filter. */ + WebRtcIsac_PitchfilterPost(LPw, LPw_pf, &ISACdecLB_obj->pitchfiltstr_obj, + PitchLags, PitchGains); + /* Convert AvgPitchGain back to float for computation of gain. */ + AvgPitchGain = ((float)AvgPitchGain_Q12) / 4096; gain = 1.0f - 0.45f * (float)AvgPitchGain; for (k = 0; k < FRAMESAMPLES_HALF; k++) { - /* reduce gain to compensate for pitch enhancer */ - LPw_pf[ k ] *= gain; + /* Reduce gain to compensate for pitch enhancer. */ + LPw_pf[k] *= gain; } - if(isRCUPayload) - { + if (isRCUPayload) { for (k = 0; k < FRAMESAMPLES_HALF; k++) { - /* compensation for transcoding gain changes*/ + /* Compensation for transcoding gain changes. */ LPw_pf[k] *= RCU_TRANSCODING_SCALE; - HPw[k] *= RCU_TRANSCODING_SCALE; + HPw[k] *= RCU_TRANSCODING_SCALE; } } - - /* perceptual post-filtering (using normalized lattice filter) */ + /* Perceptual post-filtering (using normalized lattice filter). */ WebRtcIsac_NormLatticeFilterAr( ORDERLO, ISACdecLB_obj->maskfiltstr_obj.PostStateLoF, (ISACdecLB_obj->maskfiltstr_obj).PostStateLoG, LPw_pf, lo_filt_coef, @@ -175,12 +165,11 @@ WebRtcIsac_DecodeLb( (ISACdecLB_obj->maskfiltstr_obj).PostStateHiG, HPw, hi_filt_coef, HP_dec_float); - /* recombine the 2 bands */ + /* Recombine the 2 bands. */ WebRtcIsac_FilterAndCombineFloat(LP_dec_float, HP_dec_float, - signal_out + frame_nb * processed_samples, + signal_out + frame_nb * FRAMESAMPLES, &ISACdecLB_obj->postfiltbankstr_obj); } - return len; } @@ -192,63 +181,56 @@ WebRtcIsac_DecodeLb( * Contrary to lower-band, the upper-band (8-16 kHz) is not split in * frequency, but split to 12 sub-frames, i.e. twice as lower-band. */ -int -WebRtcIsac_DecodeUb16( - float* signal_out, - ISACUBDecStruct* ISACdecUB_obj, - WebRtc_Word16 isRCUPayload) -{ +int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdecUB_obj, + WebRtc_Word16 isRCUPayload) { int len, err; double halfFrameFirst[FRAMESAMPLES_HALF]; double halfFrameSecond[FRAMESAMPLES_HALF]; - double percepFilterParam[(UB_LPC_ORDER+1) * (SUBFRAMES<<1) + - (UB_LPC_ORDER+1)]; + double percepFilterParam[(UB_LPC_ORDER + 1) * (SUBFRAMES << 1) + + (UB_LPC_ORDER + 1)]; double real_f[FRAMESAMPLES_HALF]; double imag_f[FRAMESAMPLES_HALF]; - + const WebRtc_Word16 kAveragePitchGain = 0; /* No pitch-gain for upper-band. */ len = 0; - /* decode & dequantize FiltCoef */ + /* Decode & de-quantize filter coefficients. */ memset(percepFilterParam, 0, sizeof(percepFilterParam)); err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, percepFilterParam, isac16kHz); - if (err < 0) { // error check + if (err < 0) { return err; } - /* decode & dequantize spectrum */ - len = WebRtcIsac_DecodeSpecUB16(&ISACdecUB_obj->bitstr_obj, real_f, - imag_f); - if (len < 0) { // error check + /* Decode & de-quantize spectrum. */ + len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain, + kIsacUpperBand16, real_f, imag_f); + if (len < 0) { return len; } - if(isRCUPayload) - { + if (isRCUPayload) { int n; - for(n = 0; n < 240; n++) - { + for (n = 0; n < 240; n++) { real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; } } - - /* inverse transform */ + /* Inverse transform. */ WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond, - &ISACdecUB_obj->fftstr_obj); + &ISACdecUB_obj->fftstr_obj); - /* perceptual post-filtering (using normalized lattice filter) */ + /* Perceptual post-filtering (using normalized lattice filter). */ WebRtcIsac_NormLatticeFilterAr( UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF, (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameFirst, - &percepFilterParam[(UB_LPC_ORDER+1)], signal_out); + &percepFilterParam[(UB_LPC_ORDER + 1)], signal_out); WebRtcIsac_NormLatticeFilterAr( UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF, (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, halfFrameSecond, - &percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER+1)], + &percepFilterParam[(UB_LPC_ORDER + 1) * SUBFRAMES + (UB_LPC_ORDER + 1)], &signal_out[FRAMESAMPLES_HALF]); return len; @@ -263,12 +245,8 @@ WebRtcIsac_DecodeUb16( * reconstructed and 12-16 kHz replaced with zeros. Then two bands * are combined, to reconstruct the upperband 8-16 kHz. */ -int -WebRtcIsac_DecodeUb12( - float* signal_out, - ISACUBDecStruct* ISACdecUB_obj, - WebRtc_Word16 isRCUPayload) -{ +int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdecUB_obj, + WebRtc_Word16 isRCUPayload) { int len, err; float LP_dec_float[FRAMESAMPLES_HALF]; @@ -277,54 +255,45 @@ WebRtcIsac_DecodeUb12( double LPw[FRAMESAMPLES_HALF]; double HPw[FRAMESAMPLES_HALF]; - double percepFilterParam[(UB_LPC_ORDER+1)*SUBFRAMES]; + double percepFilterParam[(UB_LPC_ORDER + 1)*SUBFRAMES]; double real_f[FRAMESAMPLES_HALF]; double imag_f[FRAMESAMPLES_HALF]; - + const WebRtc_Word16 kAveragePitchGain = 0; /* No pitch-gain for upper-band. */ len = 0; - /* decode & dequantize FiltCoef */ + /* Decode & dequantize filter coefficients. */ err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, percepFilterParam, isac12kHz); - if(err < 0) { // error check + if (err < 0) { return err; } - /* decode & dequantize spectrum */ - len = WebRtcIsac_DecodeSpecUB12(&ISACdecUB_obj->bitstr_obj, - real_f, imag_f); - if(len < 0) { // error check + /* Decode & de-quantize spectrum. */ + len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain, + kIsacUpperBand12, real_f, imag_f); + if (len < 0) { return len; } - if(isRCUPayload) - { + if (isRCUPayload) { int n; - for(n = 0; n < 240; n++) - { + for (n = 0; n < 240; n++) { real_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; imag_f[n] *= RCU_TRANSCODING_SCALE_UB_INVERSE; } } - - /* inverse transform */ + /* Inverse transform. */ WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj); - /* perceptual post-filtering (using normalized lattice filter) */ WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER, ISACdecUB_obj->maskfiltstr_obj.PostStateLoF, (ISACdecUB_obj->maskfiltstr_obj).PostStateLoG, LPw, percepFilterParam, LP_dec_float); - - /* Zerro for upper-band */ + /* Zero for 12-16 kHz. */ memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF)); - - /* recombine the 2 bands */ + /* Recombine the 2 bands. */ WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out, &ISACdecUB_obj->postfiltbankstr_obj); - - - return len; } diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/encode.c b/src/modules/audio_coding/codecs/iSAC/main/source/encode.c index 07aa69d8a1..f6bdc17d11 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/encode.c +++ b/src/modules/audio_coding/codecs/iSAC/main/source/encode.c @@ -19,6 +19,7 @@ #include #include +#include #include "structs.h" #include "codec.h" @@ -38,6 +39,7 @@ #define UB_LOOKAHEAD 24 + /* Rate allocation tables of lower and upper-band bottleneck for 12kHz & 16kHz bandwidth. @@ -67,17 +69,17 @@ */ -// 38 39.17 40.33 41.5 42.67 43.83 45 +/* 38 39.17 40.33 41.5 42.67 43.83 45 */ static const WebRtc_Word16 kLowerBandBitRate12[7] = { - 29000, 30000, 30000, 31000, 31000, 32000, 32000}; + 29000, 30000, 30000, 31000, 31000, 32000, 32000 }; static const WebRtc_Word16 kUpperBandBitRate12[7] = { - 25000, 25000, 27000, 27000, 29000, 29000, 32000}; + 25000, 25000, 27000, 27000, 29000, 29000, 32000 }; -// 50 51.2 52.4 53.6 54.8 56 +/* 50 51.2 52.4 53.6 54.8 56 */ static const WebRtc_Word16 kLowerBandBitRate16[6] = { - 31000, 31000, 32000, 32000, 32000, 32000}; + 31000, 31000, 32000, 32000, 32000, 32000 }; static const WebRtc_Word16 kUpperBandBitRate16[6] = { - 28000, 29000, 29000, 30000, 31000, 32000}; + 28000, 29000, 29000, 30000, 31000, 32000 }; /****************************************************************************** * WebRtcIsac_RateAllocation() @@ -97,68 +99,57 @@ static const WebRtc_Word16 kUpperBandBitRate16[6] = { * -1 if failed to allocate rates. */ -WebRtc_Word16 -WebRtcIsac_RateAllocation( - WebRtc_Word32 inRateBitPerSec, - double* rateLBBitPerSec, - double* rateUBBitPerSec, - enum ISACBandwidth* bandwidthKHz) -{ +WebRtc_Word16 WebRtcIsac_RateAllocation(WebRtc_Word32 inRateBitPerSec, + double* rateLBBitPerSec, + double* rateUBBitPerSec, + enum ISACBandwidth* bandwidthKHz) { WebRtc_Word16 idx; double idxD; double idxErr; - if(inRateBitPerSec < 38000) - { - // If the given overall bottleneck is less than 38000 then - // then codec has to operate in wideband mode, i.e. 8 kHz - // bandwidth. - *rateLBBitPerSec = (WebRtc_Word16)((inRateBitPerSec > 32000)? - 32000:inRateBitPerSec); + if (inRateBitPerSec < 38000) { + /* If the given overall bottleneck is less than 38000 then + * then codec has to operate in wideband mode, i.e. 8 kHz + * bandwidth. */ + *rateLBBitPerSec = (WebRtc_Word16)((inRateBitPerSec > 32000) ? + 32000 : inRateBitPerSec); *rateUBBitPerSec = 0; *bandwidthKHz = isac8kHz; - } - else if((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) - { - // At a bottleneck between 38 and 50 kbps the codec is operating - // at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates - // upper/lower bottleneck + } else if ((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) { + /* At a bottleneck between 38 and 50 kbps the codec is operating + * at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates + * upper/lower bottleneck */ - // find the bottlenecks by linear interpolation - // step is (45000 - 38000)/6.0 we use the inverse of it. + /* Find the bottlenecks by linear interpolation, + * step is (45000 - 38000)/6.0 we use the inverse of it. */ const double stepSizeInv = 8.5714286e-4; idxD = (inRateBitPerSec - 38000) * stepSizeInv; - idx = (idxD >= 6)? 6:((WebRtc_Word16)idxD); + idx = (idxD >= 6) ? 6 : ((WebRtc_Word16)idxD); idxErr = idxD - idx; *rateLBBitPerSec = kLowerBandBitRate12[idx]; *rateUBBitPerSec = kUpperBandBitRate12[idx]; - if(idx < 6) - { + if (idx < 6) { *rateLBBitPerSec += (WebRtc_Word16)( - idxErr *(kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx])); + idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx])); *rateUBBitPerSec += (WebRtc_Word16)( - idxErr *(kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx])); + idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx])); } - *bandwidthKHz = isac12kHz; - } - else if((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) - { - // A bottleneck between 50 and 56 kbps corresponds to bandwidth - // of 16 kHz. Using xxxBandBitRate16[] to calculates - // upper/lower bottleneck + } else if ((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) { + /* A bottleneck between 50 and 56 kbps corresponds to bandwidth + * of 16 kHz. Using xxxBandBitRate16[] to calculates + * upper/lower bottleneck. */ - // find the bottlenecks by linear interpolation - // step is (56000 - 50000)/5 we use the inverse of it + /* Find the bottlenecks by linear interpolation + * step is (56000 - 50000)/5 we use the inverse of it. */ const double stepSizeInv = 8.3333333e-4; idxD = (inRateBitPerSec - 50000) * stepSizeInv; - idx = (idxD >= 5)? 5:((WebRtc_Word16)idxD); + idx = (idxD >= 5) ? 5 : ((WebRtc_Word16)idxD); idxErr = idxD - idx; *rateLBBitPerSec = kLowerBandBitRate16[idx]; *rateUBBitPerSec = kUpperBandBitRate16[idx]; - if(idx < 5) - { + if (idx < 5) { *rateLBBitPerSec += (WebRtc_Word16)(idxErr * (kLowerBandBitRate16[idx + 1] - kLowerBandBitRate16[idx])); @@ -167,38 +158,35 @@ WebRtcIsac_RateAllocation( (kUpperBandBitRate16[idx + 1] - kUpperBandBitRate16[idx])); } - *bandwidthKHz = isac16kHz; - } - else - { - // Out-of-range botlteneck value. + } else { + /* Out-of-range botlteneck value. */ return -1; } - // limit the values. - *rateLBBitPerSec = (*rateLBBitPerSec > 32000)? 32000:*rateLBBitPerSec; - *rateUBBitPerSec = (*rateUBBitPerSec > 32000)? 32000:*rateUBBitPerSec; - + /* limit the values. */ + *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec; + *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec; return 0; } +void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) { + bit_stream->W_upper = 0xFFFFFFFF; + bit_stream->stream_index = 0; + bit_stream->streamval = 0; +} -int -WebRtcIsac_EncodeLb( - float* in, - ISACLBEncStruct* ISACencLB_obj, - WebRtc_Word16 codingMode, - WebRtc_Word16 bottleneckIndex) -{ +int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj, + WebRtc_Word16 codingMode, + WebRtc_Word16 bottleneckIndex) { int stream_length = 0; int err; int k; int iterCntr; - double lofilt_coef[(ORDERLO+1)*SUBFRAMES]; - double hifilt_coef[(ORDERHI+1)*SUBFRAMES]; + double lofilt_coef[(ORDERLO + 1)*SUBFRAMES]; + double hifilt_coef[(ORDERHI + 1)*SUBFRAMES]; float LP[FRAMESAMPLES_HALF]; float HP[FRAMESAMPLES_HALF]; @@ -218,58 +206,53 @@ WebRtcIsac_EncodeLb( WebRtc_Word16 AvgPitchGain_Q12; int frame_mode; /* 0 for 30ms, 1 for 60ms */ - int processed_samples, status = 0; - + int status = 0; + int my_index; transcode_obj transcodingParam; double bytesLeftSpecCoding; WebRtc_UWord16 payloadLimitBytes; - /* copy new frame length and bottle neck rate only for the first - 10 ms data */ + /* Copy new frame-length and bottleneck rate only for the first 10 ms data */ if (ISACencLB_obj->buffer_index == 0) { - /* set the framelength for the next packet */ + /* Set the framelength for the next packet. */ ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength; } - /* frame_mode is 0 (30 ms) or 1 (60 ms) */ - frame_mode = ISACencLB_obj->current_framesamples/MAX_FRAMESAMPLES; - /* processed_samples: 480 (30, 60 ms) */ - processed_samples = ISACencLB_obj->current_framesamples/(frame_mode+1); + /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */ + frame_mode = ISACencLB_obj->current_framesamples / MAX_FRAMESAMPLES; - /* buffer speech samples (by 10ms packet) until the framelength */ - /* is reached (30 or 60 ms) */ - /****************************************************************/ + /* buffer speech samples (by 10ms packet) until the frame-length */ + /* is reached (30 or 60 ms). */ + /*****************************************************************/ /* fill the buffer with 10ms input data */ for (k = 0; k < FRAMESAMPLES_10ms; k++) { ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = in[k]; } - /* if buffersize is not equal to current framesize then increase index - and return. We do no encoding untill we have enough audio. */ - if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) { + /* If buffersize is not equal to current framesize then increase index + * and return. We do no encoding untill we have enough audio. */ + if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) { ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms; return 0; } - /* if buffer reached the right size, reset index and continue with - encoding the frame */ + /* If buffer reached the right size, reset index and continue with + * encoding the frame. */ ISACencLB_obj->buffer_index = 0; - /* end of buffer function */ + /* End of buffer function. */ /**************************/ - /* encoding */ + /* Encoding */ /************/ - if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0 ) { - // This is to avoid Linux warnings until we change 'int' to 'Word32' - // at all places. + if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) { + /* This is to avoid Linux warnings until we change 'int' to 'Word32' + * at all places. */ int intVar; /* reset bitstream */ - ISACencLB_obj->bitstr_obj.W_upper = 0xFFFFFFFF; - ISACencLB_obj->bitstr_obj.streamval = 0; - ISACencLB_obj->bitstr_obj.stream_index = 0; + WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj)); - if((codingMode == 0) && (frame_mode == 0) && + if ((codingMode == 0) && (frame_mode == 0) && (ISACencLB_obj->enforceFrameSize == 0)) { ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength( ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples); @@ -278,49 +261,48 @@ WebRtcIsac_EncodeLb( ISACencLB_obj->s2nr = WebRtcIsac_GetSnr( ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples); - /* encode frame length */ + /* Encode frame length. */ status = WebRtcIsac_EncodeFrameLen( ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj); if (status < 0) { - /* Wrong frame size */ + /* Wrong frame size. */ return status; } - /* Save framelength for multiple packets memory */ + /* Save framelength for multiple packets memory. */ ISACencLB_obj->SaveEnc_obj.framelength = ISACencLB_obj->current_framesamples; - /* To be used for Redundant Coding */ + /* To be used for Redundant Coding. */ ISACencLB_obj->lastBWIdx = bottleneckIndex; intVar = (int)bottleneckIndex; WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj); } - /* split signal in two bands */ + /* Split signal in two bands. */ WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP, LP_lookahead, HP_lookahead, - &ISACencLB_obj->prefiltbankstr_obj ); + &ISACencLB_obj->prefiltbankstr_obj); /* estimate pitch parameters and pitch-filter lookahead signal */ WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf, &ISACencLB_obj->pitchanalysisstr_obj, PitchLags, PitchGains); - /* encode in FIX Q12 */ + /* Encode in FIX Q12. */ - /* convert PitchGain to Fixed point */ - for (k=0;kframe_nb == 0) - { + /* Set where to store data in multiple packets memory. */ + if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) { ISACencLB_obj->SaveEnc_obj.startIdx = 0; } else { ISACencLB_obj->SaveEnc_obj.startIdx = 1; } - /* quantize & encode pitch parameters */ + /* Quantize & encode pitch parameters. */ WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12, @@ -330,21 +312,21 @@ WebRtcIsac_EncodeLb( AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2; - /* find coefficients for perceptual pre-filters */ + /* Find coefficients for perceptual pre-filters. */ WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead, &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr, PitchGains_Q12, lofilt_coef, hifilt_coef); - /* code LPC model and shape - gains not quantized yet */ + /* Code LPC model and shape - gains not quantized yet. */ WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); - /* convert PitchGains back to FLOAT for pitchfilter_pre */ + /* Convert PitchGains back to FLOAT for pitchfilter_pre. */ for (k = 0; k < 4; k++) { - PitchGains[k] = ((float)PitchGains_Q12[k])/4096; + PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096; } - /* Store the state of arithmetic coder before coding LPC gains */ + /* Store the state of arithmetic coder before coding LPC gains. */ transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper; transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index; transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval; @@ -357,10 +339,10 @@ WebRtcIsac_EncodeLb( transcodingParam.stream[2] = ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index]; - /* Store LPC Gains before encoding them */ - for(k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER+1)*k]; - transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER+1)*k]; + /* Store LPC Gains before encoding them. */ + for (k = 0; k < SUBFRAMES; k++) { + transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k]; + transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k]; } /* Code gains */ @@ -369,59 +351,53 @@ WebRtcIsac_EncodeLb( &ISACencLB_obj->SaveEnc_obj); /* Get the correct value for the payload limit and calculate the - number of bytes left for coding the spectrum.*/ - if((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { + * number of bytes left for coding the spectrum. */ + if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { /* It is a 60ms and we are in the first 30ms then the limit at - this point should be half of the assigned value */ + * this point should be half of the assigned value. */ payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1; - } - else if (frame_mode == 0) { + } else if (frame_mode == 0) { /* It is a 30ms frame */ - /* Subract 3 because termination process may add 3 bytes */ + /* Subract 3 because termination process may add 3 bytes. */ payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3; } else { /* This is the second half of a 60ms frame. */ - /* Subract 3 because termination process may add 3 bytes */ + /* Subract 3 because termination process may add 3 bytes. */ payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3; } bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index; - /* perceptual pre-filtering (using normalized lattice filter) */ - /* low-band filtering */ + /* Perceptual pre-filtering (using normalized lattice filter). */ + /* Low-band filtering. */ WebRtcIsac_NormLatticeFilterMa(ORDERLO, ISACencLB_obj->maskfiltstr_obj.PreStateLoF, ISACencLB_obj->maskfiltstr_obj.PreStateLoG, LP, lofilt_coef, LPw); - /* high-band filtering */ + /* High-band filtering. */ WebRtcIsac_NormLatticeFilterMa(ORDERHI, ISACencLB_obj->maskfiltstr_obj.PreStateHiF, ISACencLB_obj->maskfiltstr_obj.PreStateHiG, HP, hifilt_coef, HPw); - - - /* pitch filter */ + /* Pitch filter. */ WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj, PitchLags, PitchGains); - - /* transform */ + /* Transform */ WebRtcIsac_Time2Spec(LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj); - /* Save data for multiple packets memory */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - ISACencLB_obj->SaveEnc_obj.fre[k + ISACencLB_obj->SaveEnc_obj.startIdx * - FRAMESAMPLES_HALF] = fre[k]; - ISACencLB_obj->SaveEnc_obj.fim[k + ISACencLB_obj->SaveEnc_obj.startIdx * - FRAMESAMPLES_HALF] = fim[k]; - } + /* Save data for multiple packets memory. */ + my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF; + memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre)); + memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim)); + ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] = AvgPitchGain_Q12; - /* quantization and lossless coding */ - err = WebRtcIsac_EncodeSpecLb(fre, fim, &ISACencLB_obj->bitstr_obj, - AvgPitchGain_Q12); + /* Quantization and loss-less coding. */ + err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand, + &ISACencLB_obj->bitstr_obj); if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { /* There has been an error but it was not too large payload - (we can cure too large payload) */ + (we can cure too large payload). */ if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) { /* If this is the second 30ms of a 60ms frame reset this such that in the next call encoder starts fresh. */ @@ -430,34 +406,34 @@ WebRtcIsac_EncodeLb( return err; } iterCntr = 0; - while((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) || + while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) || (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { double bytesSpecCoderUsed; double transcodeScale; - if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { + if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { /* We were not able to limit the payload size */ - if((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { + if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) { /* This was the first 30ms of a 60ms frame. Although the payload is larger than it should be but we let the second 30ms be encoded. Maybe together we won't exceed the limit. */ ISACencLB_obj->frame_nb = 1; return 0; - } else if((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) { + } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) { ISACencLB_obj->frame_nb = 0; } - if(err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) { + if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) { return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; } else { return status; } } - if(err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { + if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { bytesSpecCoderUsed = STREAM_SIZE_MAX; - // being coservative + /* Being conservative */ transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; } else { bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index - @@ -470,31 +446,28 @@ WebRtcIsac_EncodeLb( transcodeScale *= (1.0 - (0.9 * (double)iterCntr / (double)MAX_PAYLOAD_LIMIT_ITERATION)); - /* Scale the LPC Gains */ + /* Scale the LPC Gains. */ for (k = 0; k < SUBFRAMES; k++) { - lofilt_coef[(LPC_LOBAND_ORDER+1) * k] = + lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] = transcodingParam.loFiltGain[k] * transcodeScale; - hifilt_coef[(LPC_HIBAND_ORDER+1) * k] = + hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] = transcodingParam.hiFiltGain[k] * transcodeScale; - transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER+1) * k]; - transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER+1) * k]; + transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k]; + transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k]; } - /* Scale DFT coefficients */ + /* Scale DFT coefficients. */ for (k = 0; k < FRAMESAMPLES_HALF; k++) { fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale); fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale); } - /* Save data for multiple packets memory */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - ISACencLB_obj->SaveEnc_obj.fre[k + ISACencLB_obj->SaveEnc_obj.startIdx * - FRAMESAMPLES_HALF] = fre[k]; - ISACencLB_obj->SaveEnc_obj.fim[k + ISACencLB_obj->SaveEnc_obj.startIdx * - FRAMESAMPLES_HALF] = fim[k]; - } + /* Save data for multiple packets memory. */ + my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF; + memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre)); + memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim)); - /* Re-store the state of arithmetic coder before coding LPC gains */ + /* Re-store the state of arithmetic coder before coding LPC gains. */ ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval; @@ -505,23 +478,23 @@ WebRtcIsac_EncodeLb( ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.stream[2]; - /* Code gains */ + /* Code gains. */ WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj, &ISACencLB_obj->SaveEnc_obj); - /* Update the number of bytes left for encoding the spectrum */ - bytesLeftSpecCoding = payloadLimitBytes - - transcodingParam.stream_index; + /* Update the number of bytes left for encoding the spectrum. */ + bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index; - /* Encode the spectrum */ - err = WebRtcIsac_EncodeSpecLb(fre, fim, &ISACencLB_obj->bitstr_obj, - AvgPitchGain_Q12); - if((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { + /* Encode the spectrum. */ + err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand, + &ISACencLB_obj->bitstr_obj); + + if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { /* There has been an error but it was not too large - payload (we can cure too large payload) */ + payload (we can cure too large payload). */ if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) { - /* If this is the second 30ms of a 60ms frame reset + /* If this is the second 30 ms of a 60 ms frame reset this such that in the next call encoder starts fresh. */ ISACencLB_obj->frame_nb = 0; } @@ -530,50 +503,151 @@ WebRtcIsac_EncodeLb( iterCntr++; } - /* i.e. 60 ms framesize and just processed the first 30ms, */ - /* go back to main function to buffer the other 30ms speech frame */ - if (frame_mode == 1) - { - if(ISACencLB_obj->frame_nb == 0) - { + /* If 60 ms frame-size and just processed the first 30 ms, */ + /* go back to main function to buffer the other 30 ms speech frame. */ + if (frame_mode == 1) { + if (ISACencLB_obj->frame_nb == 0) { ISACencLB_obj->frame_nb = 1; return 0; - } - else if(ISACencLB_obj->frame_nb == 1) - { + } else if (ISACencLB_obj->frame_nb == 1) { ISACencLB_obj->frame_nb = 0; - /* also update the framelength for next packet, - in Adaptive mode only */ - if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) - { + /* Also update the frame-length for next packet, + in Adaptive mode only. */ + if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) { ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples); } } - } - else - { + } else { ISACencLB_obj->frame_nb = 0; } - /* complete arithmetic coding */ + /* Complete arithmetic coding. */ stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj); - return stream_length; } -int -WebRtcIsac_EncodeUb16( - float* in, - ISACUBEncStruct* ISACencUB_obj, - WebRtc_Word32 jitterInfo) -{ + + +static int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj, + WebRtc_UWord16 payloadLimitBytes, + double bytesLeftSpecCoding, + transcode_obj* transcodingParam, + WebRtc_Word16* fre, WebRtc_Word16* fim, + double* lpcGains, enum ISACBand band, int status) { + + int iterCntr = 0; + int k; + double bytesSpecCoderUsed; + double transcodeScale; + const WebRtc_Word16 kAveragePitchGain = 0.0; + + do { + if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { + /* We were not able to limit the payload size. */ + return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; + } + + if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { + bytesSpecCoderUsed = STREAM_SIZE_MAX; + /* Being conservative. */ + transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; + } else { + bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index - + transcodingParam->stream_index; + transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; + } + + /* To be safe, we reduce the scale depending on the + number of iterations. */ + transcodeScale *= (1.0 - (0.9 * (double)iterCntr / + (double)MAX_PAYLOAD_LIMIT_ITERATION)); + + /* Scale the LPC Gains. */ + if (band == kIsacUpperBand16) { + /* Two sets of coefficients if 16 kHz. */ + for (k = 0; k < SUBFRAMES; k++) { + transcodingParam->loFiltGain[k] *= transcodeScale; + transcodingParam->hiFiltGain[k] *= transcodeScale; + } + } else { + /* One sets of coefficients if 12 kHz. */ + for (k = 0; k < SUBFRAMES; k++) { + transcodingParam->loFiltGain[k] *= transcodeScale; + } + } + + /* Scale DFT coefficients. */ + for (k = 0; k < FRAMESAMPLES_HALF; k++) { + fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5); + fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5); + } + /* Store FFT coefficients for multiple encoding. */ + memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, + sizeof(ISACencUB_obj->SaveEnc_obj.realFFT)); + memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, + sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT)); + + /* Store the state of arithmetic coder before coding LPC gains */ + ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper; + ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index; + ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval; + ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] = + transcodingParam->stream[0]; + ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] = + transcodingParam->stream[1]; + ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] = + transcodingParam->stream[2]; + + /* Store the gains for multiple encoding. */ + memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, + SUBFRAMES * sizeof(double)); + /* Entropy Code lpc-gains, indices are stored for a later use.*/ + WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain, + &ISACencUB_obj->bitstr_obj, + ISACencUB_obj->SaveEnc_obj.lpcGainIndex); + + /* If 16kHz should do one more set. */ + if (band == kIsacUpperBand16) { + /* Store the gains for multiple encoding. */ + memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES], + &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double)); + /* Entropy Code lpc-gains, indices are stored for a later use.*/ + WebRtcIsac_EncodeLpcGainUb( + transcodingParam->hiFiltGain, &ISACencUB_obj->bitstr_obj, + &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]); + } + + /* Update the number of bytes left for encoding the spectrum. */ + bytesLeftSpecCoding = payloadLimitBytes - + ISACencUB_obj->bitstr_obj.stream_index; + + /* Save the bit-stream object at this point for FEC. */ + memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, + &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); + + /* Encode the spectrum. */ + status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, + band, &ISACencUB_obj->bitstr_obj); + if ((status < 0) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { + /* There has been an error but it was not too large payload + (we can cure too large payload). */ + return status; + } + iterCntr++; + } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || + (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH)); + return 0; +} + +int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj, + WebRtc_Word32 jitterInfo) { int err; int k; double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; - double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES<<1) + + double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES << 1) + (1 + UB_LPC_ORDER)]; double LP_lookahead[FRAMESAMPLES]; @@ -583,44 +657,39 @@ WebRtcIsac_EncodeUb16( int status = 0; double varscale[2]; - double corr[SUBFRAMES<<1][UB_LPC_ORDER + 1]; - double lpcGains[SUBFRAMES<<1]; + double corr[SUBFRAMES << 1][UB_LPC_ORDER + 1]; + double lpcGains[SUBFRAMES << 1]; transcode_obj transcodingParam; - double bytesLeftSpecCoding; WebRtc_UWord16 payloadLimitBytes; - WebRtc_UWord16 iterCntr; double s2nr; + const WebRtc_Word16 kAveragePitchGain = 0.0; + int bytesLeftSpecCoding; - /* buffer speech samples (by 10ms packet) until the framelength is */ - /* reached (30 or 60 ms) */ + /* Buffer speech samples (by 10ms packet) until the frame-length is */ + /* reached (30 ms). */ /*********************************************************************/ /* fill the buffer with 10ms input data */ - for (k = 0; k < FRAMESAMPLES_10ms; k++) { - ISACencUB_obj->data_buffer_float[k + ISACencUB_obj->buffer_index] = - in[k]; - } + memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in, + FRAMESAMPLES_10ms * sizeof(float)); - /* if buffersize is not equal to current framesize, and end of file is - not reached yet, we don't do encoding unless we have the whole frame */ + /* If buffer size is not equal to current frame-size, and end of file is + * not reached yet, we don't do encoding unless we have the whole frame. */ if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) { ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms; return 0; } - /* end of buffer function */ + /* End of buffer function. */ /**************************/ - /* encoding */ + /* Encoding */ /************/ - /* reset bitstream */ - ISACencUB_obj->bitstr_obj.W_upper = 0xFFFFFFFF; - ISACencUB_obj->bitstr_obj.streamval = 0; - ISACencUB_obj->bitstr_obj.stream_index = 0; + /* Reset bit-stream */ + WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj)); - /* bandwidth estimation and coding */ - /* To be used for Redundant Coding */ + /* Encoding of bandwidth information. */ WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj); status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj); @@ -628,8 +697,7 @@ WebRtcIsac_EncodeUb16( return status; } - s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, - FRAMESAMPLES); + s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES); memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double)); @@ -637,7 +705,7 @@ WebRtcIsac_EncodeUb16( LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k]; } - /* find coefficients for perceptual pre-filters */ + /* Find coefficients for perceptual pre-filters. */ WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj, &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz); @@ -645,15 +713,15 @@ WebRtcIsac_EncodeUb16( &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)], sizeof(double) * UB_LPC_ORDER); - /* code LPC model and shape - gains not quantized yet */ + /* Code LPC model and shape - gains not quantized yet. */ WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj, percepFilterParams, isac16kHz, &ISACencUB_obj->SaveEnc_obj); - // the first set of lpc parameters are from the last sub-frame of - // the previous frame. so we don't care about them + /* the first set of lpc parameters are from the last sub-frame of + * the previous frame. so we don't care about them. */ WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1], - (SUBFRAMES<<1), lpcGains, corr, varscale); + (SUBFRAMES << 1), lpcGains, corr, varscale); /* Store the state of arithmetic coder before coding LPC gains */ transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index; @@ -668,13 +736,13 @@ WebRtcIsac_EncodeUb16( transcodingParam.stream[2] = ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index]; - /* Store LPC Gains before encoding them */ - for(k = 0; k < SUBFRAMES; k++) { + /* Store LPC Gains before encoding them. */ + for (k = 0; k < SUBFRAMES; k++) { transcodingParam.loFiltGain[k] = lpcGains[k]; transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k]; } - // Store the gains for multiple encoding + /* Store the gains for multiple encoding. */ memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, (SUBFRAMES << 1) * sizeof(double)); @@ -690,15 +758,15 @@ WebRtcIsac_EncodeUb16( payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes - ISACencUB_obj->numBytesUsed - 3; bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; + ISACencUB_obj->bitstr_obj.stream_index; - for (k = 0; k < (SUBFRAMES<<1); k++) { - percepFilterParams[k*(UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] = + for (k = 0; k < (SUBFRAMES << 1); k++) { + percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] = lpcGains[k]; } - /* perceptual pre-filtering (using normalized lattice filter) */ - /* first half-frame filtering */ + /* LPC filtering (using normalized lattice filter), */ + /* first half-frame. */ WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF, ISACencUB_obj->maskfiltstr_obj.PreStateLoG, @@ -706,7 +774,7 @@ WebRtcIsac_EncodeUb16( &percepFilterParams[UB_LPC_ORDER + 1], &LP_lookahead[0]); - /* Second half-frame filtering */ + /* Second half-frame filtering. */ WebRtcIsac_NormLatticeFilterMa( UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF, ISACencUB_obj->maskfiltstr_obj.PreStateLoG, @@ -717,130 +785,51 @@ WebRtcIsac_EncodeUb16( WebRtcIsac_Time2Spec(&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF], fre, fim, &ISACencUB_obj->fftstr_obj); - //Store FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); + /* Store FFT coefficients for multiple encoding. */ + memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre)); + memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, sizeof(fim)); - // Prepare the audio buffer for the next packet - // move the last 3 ms to the beginning of the buffer + /* Prepare the audio buffer for the next packet + * move the last 3 ms to the beginning of the buffer. */ memcpy(ISACencUB_obj->data_buffer_float, &ISACencUB_obj->data_buffer_float[FRAMESAMPLES], LB_TOTAL_DELAY_SAMPLES * sizeof(float)); - // start writing with 3 ms delay to compensate for the delay - // of the lower-band. + /* start writing with 3 ms delay to compensate for the delay + * of the lower-band. */ ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES; - // Save the bit-stream object at this point for FEC. + /* Save the bit-stream object at this point for FEC. */ memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - /* quantization and lossless coding */ - err = WebRtcIsac_EncodeSpecUB16(fre, fim, &ISACencUB_obj->bitstr_obj); + /* Qantization and lossless coding */ + /* Note that there is no pitch-gain for this band so kAveragePitchGain = 0 + * is passed to the function. In fact, the function ignores the 3rd parameter + * for this band. */ + err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16, + &ISACencUB_obj->bitstr_obj); if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { return err; } - iterCntr = 0; - while((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || + if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - double bytesSpecCoderUsed; - double transcodeScale; - - if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { - /* We were not able to limit the payload size */ - return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; - } - - if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { - bytesSpecCoderUsed = STREAM_SIZE_MAX; - // being conservative - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; - } else { - bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index - - transcodingParam.stream_index; - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; - } - - /* To be safe, we reduce the scale depending on the - number of iterations. */ - transcodeScale *= (1.0 - (0.9 * (double)iterCntr/ - (double)MAX_PAYLOAD_LIMIT_ITERATION)); - - /* Scale the LPC Gains */ - for (k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] *= transcodeScale; - transcodingParam.hiFiltGain[k] *= transcodeScale; - } - - /* Scale DFT coefficients */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5); - fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5); - } - - //Store FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); - - - /* Store the state of arithmetic coder before coding LPC gains */ - ISACencUB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; - ISACencUB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; - ISACencUB_obj->bitstr_obj.streamval = transcodingParam.streamval; - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] = - transcodingParam.stream[0]; - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] = - transcodingParam.stream[1]; - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index] = - transcodingParam.stream[2]; - - // Store the gains for multiple encoding - memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, - (SUBFRAMES << 1) * sizeof(double)); - - WebRtcIsac_EncodeLpcGainUb(transcodingParam.loFiltGain, - &ISACencUB_obj->bitstr_obj, - ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - WebRtcIsac_EncodeLpcGainUb( - transcodingParam.hiFiltGain, &ISACencUB_obj->bitstr_obj, - &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]); - - /* Update the number of bytes left for encoding the spectrum */ - bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; - - // Save the bit-stream object at this point for FEC. - memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, - &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - - /* Encode the spectrum */ - err = WebRtcIsac_EncodeSpecUB16(fre, fim, &ISACencUB_obj->bitstr_obj); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large payload - (we can cure too large payload) */ - return err; - } - iterCntr++; + err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding, + &transcodingParam, fre, fim, lpcGains, + kIsacUpperBand16, err); } - - /* complete arithmetic coding */ + if (err < 0) { + return err; + } + /* Complete arithmetic coding. */ return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj); } -int -WebRtcIsac_EncodeUb12( - float* in, - ISACUBEncStruct* ISACencUB_obj, - WebRtc_Word32 jitterInfo) -{ +int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACencUB_obj, + WebRtc_Word32 jitterInfo) { int err; int k; - int iterCntr; double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME]; @@ -863,18 +852,18 @@ WebRtcIsac_EncodeUb12( double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1]; double lpcGains[SUBFRAMES]; transcode_obj transcodingParam; - double bytesLeftSpecCoding; WebRtc_UWord16 payloadLimitBytes; double s2nr; + const WebRtc_Word16 kAveragePitchGain = 0.0; + double bytesLeftSpecCoding; - /* buffer speech samples (by 10ms packet) until the framelength is */ - /* reached (30 or 60 ms) */ + /* Buffer speech samples (by 10ms packet) until the framelength is */ + /* reached (30 ms). */ /********************************************************************/ - /* fill the buffer with 10ms input data */ - for (k=0; kdata_buffer_float[k + ISACencUB_obj->buffer_index] = in[k]; - } + /* Fill the buffer with 10ms input data. */ + memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in, + FRAMESAMPLES_10ms * sizeof(float)); /* if buffer-size is not equal to current frame-size then increase the index and return. We do the encoding when we have enough audio. */ @@ -882,25 +871,21 @@ WebRtcIsac_EncodeUb12( ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms; return 0; } - /* if buffer reached the right size, reset index and continue + /* If buffer reached the right size, reset index and continue with encoding the frame */ ISACencUB_obj->buffer_index = 0; - /* end of buffer function */ + /* End of buffer function */ /**************************/ - /* encoding */ + /* Encoding */ /************/ - /* reset bitstream */ - ISACencUB_obj->bitstr_obj.W_upper = 0xFFFFFFFF; - ISACencUB_obj->bitstr_obj.streamval = 0; - ISACencUB_obj->bitstr_obj.stream_index = 0; + /* Reset bit-stream. */ + WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj)); - /* bandwidth estimation and coding */ - /* To be used for Redundant Coding */ + /* Encoding bandwidth information. */ WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj); - status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj); if (status < 0) { return status; @@ -908,16 +893,16 @@ WebRtcIsac_EncodeUb12( s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES); - /* split signal in two bands */ + /* Split signal in two bands. */ WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP, HP_lookahead, LP_lookahead, &ISACencUB_obj->prefiltbankstr_obj); - /* find coefficients for perceptual pre-filters */ + /* Find coefficients for perceptual pre-filters. */ WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj, lpcVecs, corr, varscale, isac12kHz); - /* code LPC model and shape - gains not quantized yet */ + /* Code LPC model and shape - gains not quantized yet. */ WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj, percepFilterParams, isac12kHz, &ISACencUB_obj->SaveEnc_obj); @@ -925,7 +910,7 @@ WebRtcIsac_EncodeUb12( WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr, varscale); - /* Store the state of arithmetic coder before coding LPC gains */ + /* Store the state of arithmetic coder before coding LPC gains. */ transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper; transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index; transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval; @@ -938,20 +923,20 @@ WebRtcIsac_EncodeUb12( transcodingParam.stream[2] = ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index]; - /* Store LPC Gains before encoding them */ - for(k = 0; k < SUBFRAMES; k++) { + /* Store LPC Gains before encoding them. */ + for (k = 0; k < SUBFRAMES; k++) { transcodingParam.loFiltGain[k] = lpcGains[k]; } - // Store the gains for multiple encoding + /* Store the gains for multiple encoding. */ memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES * sizeof(double)); WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj, ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - for(k = 0; k < SUBFRAMES; k++) { - percepFilterParams[k*(UB_LPC_ORDER + 1)] = lpcGains[k]; + for (k = 0; k < SUBFRAMES; k++) { + percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k]; } /* perceptual pre-filtering (using normalized lattice filter) */ @@ -969,117 +954,43 @@ WebRtcIsac_EncodeUb12( bytesLeftSpecCoding = payloadLimitBytes - ISACencUB_obj->bitstr_obj.stream_index; - memset(HPw, 0, sizeof(double) * FRAMESAMPLES_HALF); + memset(HPw, 0, sizeof(HPw)); - /* transform */ + /* Transform */ WebRtcIsac_Time2Spec(LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj); - //Store real FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); + /* Store FFT coefficients for multiple encoding. */ + memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, + sizeof(ISACencUB_obj->SaveEnc_obj.realFFT)); + memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, + sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT)); - //Store imaginary FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); - - // Save the bit-stream object at this point for FEC. + /* Save the bit-stream object at this point for FEC. */ memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - /* quantization and lossless coding */ - err = WebRtcIsac_EncodeSpecUB12(fre, fim, &ISACencUB_obj->bitstr_obj); + /* Quantization and loss-less coding */ + /* The 4th parameter to this function is pitch-gain, which is only used + * when encoding 0-8 kHz band, and irrelevant in this function, therefore, + * we insert zero here. */ + err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12, + &ISACencUB_obj->bitstr_obj); if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { /* There has been an error but it was not too large payload (we can cure too large payload) */ return err; } - iterCntr = 0; - while((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || + + if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) || (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - double bytesSpecCoderUsed; - double transcodeScale; - - if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) { - /* We were not able to limit the payload size */ - return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; - } - - if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) { - bytesSpecCoderUsed = STREAM_SIZE_MAX; - // being coservative - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5; - } else { - bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index - - transcodingParam.stream_index; - transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed; - } - - /* To be safe, we reduce the scale depending on the - number of iterations. */ - transcodeScale *= (1.0 - (0.9 * (double)iterCntr/ - (double)MAX_PAYLOAD_LIMIT_ITERATION)); - - /* Scale the LPC Gains */ - for (k = 0; k < SUBFRAMES; k++) { - transcodingParam.loFiltGain[k] *= transcodeScale; - } - - /* Scale DFT coefficients */ - for (k = 0; k < FRAMESAMPLES_HALF; k++) { - fre[k] = (WebRtc_Word16)(fre[k] * transcodeScale + 0.5); - fim[k] = (WebRtc_Word16)(fim[k] * transcodeScale + 0.5); - } - - //Store real FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.realFFT, fre, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); - - //Store imaginary FFT coefficients for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.imagFFT, fim, FRAMESAMPLES_HALF * - sizeof(WebRtc_Word16)); - - - /* Re-store the state of arithmetic coder before coding LPC gains */ - ISACencUB_obj->bitstr_obj.W_upper = transcodingParam.W_upper; - ISACencUB_obj->bitstr_obj.stream_index = transcodingParam.stream_index; - ISACencUB_obj->bitstr_obj.streamval = transcodingParam.streamval; - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] = - transcodingParam.stream[0]; - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] = - transcodingParam.stream[1]; - ISACencUB_obj->bitstr_obj.stream[transcodingParam.stream_index] = - transcodingParam.stream[2]; - - // Store the gains for multiple encoding - memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES * - sizeof(double)); - - // encode LPC gain and store quantization indices. HAving quantization - // indices reduces transcoding complexity if 'scale factor' is 1. - WebRtcIsac_EncodeLpcGainUb(transcodingParam.loFiltGain, - &ISACencUB_obj->bitstr_obj, - ISACencUB_obj->SaveEnc_obj.lpcGainIndex); - - // Save the bit-stream object at this point for FEC. - memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, - &ISACencUB_obj->bitstr_obj, sizeof(Bitstr)); - - /* Update the number of bytes left for encoding the spectrum */ - bytesLeftSpecCoding = payloadLimitBytes - - ISACencUB_obj->bitstr_obj.stream_index; - - /* Encode the spectrum */ - err = WebRtcIsac_EncodeSpecUB12(fre, fim, - &ISACencUB_obj->bitstr_obj); - if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) { - /* There has been an error but it was not too large payload - (we can cure too large payload) */ - return err; - } - iterCntr++; + err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding, + &transcodingParam, fre, fim, lpcGains, + kIsacUpperBand12, err); } - - /* complete arithmetic coding */ + if (err < 0) { + return err; + } + /* Complete arithmetic coding. */ return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj); } @@ -1088,50 +999,46 @@ WebRtcIsac_EncodeUb12( -/* This function is used to create a new bitstream with new BWE. +/* This function is used to create a new bit-stream with new BWE. The same data as previously encoded with the function WebRtcIsac_Encoder(). - The data needed is taken from the struct, where it was stored + The data needed is taken from the structure, where it was stored when calling the encoder. */ -int WebRtcIsac_EncodeStoredDataLb( - const ISAC_SaveEncData_t* ISACSavedEnc_obj, - Bitstr* ISACBitStr_obj, - int BWnumber, - float scale) -{ +int WebRtcIsac_EncodeStoredDataLb(const ISAC_SaveEncData_t* ISACSavedEnc_obj, + Bitstr* ISACBitStr_obj, int BWnumber, + float scale) { int ii; int status; int BWno = BWnumber; - const WebRtc_UWord16 *WebRtcIsac_kQPitchGainCdf_ptr[1]; - const WebRtc_UWord16 **cdf; + const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1]; + const WebRtc_UWord16** cdf; - double tmpLPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*2]; - double tmpLPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*2]; - int tmpLPCindex_g[12*2]; + double tmpLPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * 2]; + double tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * 2]; + int tmpLPCindex_g[12 * 2]; WebRtc_Word16 tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES]; + const int kModel = 0; - /* Sanity Check - possible values for BWnumber is 0 - 23 */ + /* Sanity Check - possible values for BWnumber is 0 - 23. */ if ((BWnumber < 0) || (BWnumber > 23)) { return -ISAC_RANGE_ERROR_BW_ESTIMATOR; } - /* reset bitstream */ - ISACBitStr_obj->W_upper = 0xFFFFFFFF; - ISACBitStr_obj->streamval = 0; - ISACBitStr_obj->stream_index = 0; + /* Reset bit-stream. */ + WebRtcIsac_ResetBitstream(ISACBitStr_obj); - /* encode frame length */ + /* Encode frame length */ status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength, ISACBitStr_obj); if (status < 0) { - /* Wrong frame size */ + /* Wrong frame size. */ return status; } - /* Transcoding */ + /* Transcoding */ if ((scale > 0.0) && (scale < 1.0)) { - /* Compensate LPC gain */ + /* Compensate LPC gain. */ for (ii = 0; ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx)); ii++) { @@ -1142,7 +1049,7 @@ int WebRtcIsac_EncodeStoredDataLb( ii++) { tmpLPCcoeffs_hi[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_hi[ii]; } - /* Scale DFT */ + /* Scale DFT. */ for (ii = 0; ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx)); ii++) { @@ -1163,19 +1070,19 @@ int WebRtcIsac_EncodeStoredDataLb( } } - /* encode bandwidth estimate */ + /* Encode bandwidth estimate. */ WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj); /* Loop over number of 30 msec */ for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) { - /* encode pitch gains */ + /* Encode pitch gains. */ *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; WebRtcIsac_EncHistMulti(ISACBitStr_obj, &ISACSavedEnc_obj->pitchGain_index[ii], WebRtcIsac_kQPitchGainCdf_ptr, 1); - /* entropy coding of quantization pitch lags */ - /* voicing classificiation */ + /* Entropy coding of quantization pitch lags */ + /* Voicing classification. */ if (ISACSavedEnc_obj->meanGain[ii] < 0.2) { cdf = WebRtcIsac_kQPitchLagCdfPtrLo; } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) { @@ -1184,259 +1091,162 @@ int WebRtcIsac_EncodeStoredDataLb( cdf = WebRtcIsac_kQPitchLagCdfPtrHi; } WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES*ii], + &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES * ii], cdf, PITCH_SUBFRAMES); /* LPC */ - { - /* Only one model exists. The entropy coding is done only for backward - * compatibility. - */ - const int kModel = 0; - /* entropy coding of model number */ - WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &kModel, WebRtcIsac_kQKltModelCdfPtr, 1); - } - /* entropy coding of quantization indices - LPC shape only */ + /* Only one model exists. The entropy coding is done only for backward + * compatibility. */ + WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel, + WebRtcIsac_kQKltModelCdfPtr, 1); + /* Entropy coding of quantization indices - LPC shape only. */ WebRtcIsac_EncHistMulti(ISACBitStr_obj, - &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE*ii], + &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE * ii], WebRtcIsac_kQKltCdfPtrShape, KLT_ORDER_SHAPE); /* If transcoding, get new LPC gain indices */ if (scale < 1.0) { - WebRtcIsac_TranscodeLPCCoef(&tmpLPCcoeffs_lo[(ORDERLO+1) * SUBFRAMES*ii], - &tmpLPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*ii], - &tmpLPCindex_g[KLT_ORDER_GAIN * ii]); + WebRtcIsac_TranscodeLPCCoef( + &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii], + &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii], + &tmpLPCindex_g[KLT_ORDER_GAIN * ii]); } - /* entropy coding of quantization indices - LPC gain */ - WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii], + /* Entropy coding of quantization indices - LPC gain. */ + WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii], WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN); - /* quantization and lossless coding */ - status = WebRtcIsac_EncodeSpecLb(&tmp_fre[ii*FRAMESAMPLES_HALF], - &tmp_fim[ii*FRAMESAMPLES_HALF], - ISACBitStr_obj, - ISACSavedEnc_obj->AvgPitchGain[ii]); + /* Quantization and loss-less coding. */ + status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF], + &tmp_fim[ii * FRAMESAMPLES_HALF], + ISACSavedEnc_obj->AvgPitchGain[ii], + kIsacLowerBand, ISACBitStr_obj); if (status < 0) { return status; } } - - /* complete arithmetic coding */ + /* Complete arithmetic coding. */ return WebRtcIsac_EncTerminate(ISACBitStr_obj); } - - -int WebRtcIsac_EncodeStoredDataUb12( +int WebRtcIsac_EncodeStoredDataUb( const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale) -{ + Bitstr* bitStream, + WebRtc_Word32 jitterInfo, + float scale, + enum ISACBandwidth bandwidth) { int n; int err; double lpcGain[SUBFRAMES]; WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; + const WebRtc_UWord16** shape_cdf; + int shape_len; + const WebRtc_Word16 kAveragePitchGain = 0.0; + enum ISACBand band; + /* Reset bitstream. */ + WebRtcIsac_ResetBitstream(bitStream); - /* reset bitstream */ - bitStream->W_upper = 0xFFFFFFFF; - bitStream->streamval = 0; - bitStream->stream_index = 0; - - // Encode jitter index + /* Encode jitter index. */ WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream); - err = WebRtcIsac_EncodeBandwidth(isac12kHz, bitStream); - if(err < 0) - { + err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream); + if (err < 0) { return err; } - // Encode LPC-shape - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape, - WebRtcIsac_kLpcShapeCdfMatUb12, - UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); - - // we only consider scales between zero and one. - if((scale <= 0.0) || (scale > 1.0)) - { - scale = 1.0f; + /* Encode LPC-shape. */ + if (bandwidth == isac12kHz) { + shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12; + shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME; + band = kIsacUpperBand12; + } else { + shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16; + shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME; + band = kIsacUpperBand16; } + WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape, + shape_cdf, shape_len); - if(scale == 1.0f) - { - //memcpy(lpcGain, ISACSavedEnc_obj->lpcGain, SUBFRAMES * sizeof(double)); + if ((scale <= 0.0) || (scale >= 1.0)) { + /* We only consider scales between zero and one. */ WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex, WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB12(ISACSavedEnc_obj->realFFT, - ISACSavedEnc_obj->imagFFT, bitStream); - } - else - { - /* scale lpc gain and FFT coefficients */ - for(n = 0; n < SUBFRAMES; n++) - { + if (bandwidth == isac16kHz) { + /* Store gain indices of the second half. */ + WebRtcIsac_EncHistMulti(bitStream, + &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES], + WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); + } + /* Store FFT coefficients. */ + err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT, + ISACSavedEnc_obj->imagFFT, kAveragePitchGain, + band, bitStream); + } else { + /* Scale LPC gain and FFT coefficients. */ + for (n = 0; n < SUBFRAMES; n++) { lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n]; } - // store lpc gain + /* Store LPC gains. */ WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); - for(n = 0; n < FRAMESAMPLES_HALF; n++) - { + + if (bandwidth == isac16kHz) { + /* Scale and code the gains of the second half of the frame, if 16kHz. */ + for (n = 0; n < SUBFRAMES; n++) { + lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES]; + } + WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); + } + + for (n = 0; n < FRAMESAMPLES_HALF; n++) { realFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->realFFT[n] + 0.5f); imagFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->imagFFT[n] + 0.5f); } - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB12(realFFT, imagFFT, bitStream); + /* Store FFT coefficients. */ + err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, + band, bitStream); } - if(err < 0) - { - // error happened while encoding FFT coefficients. + if (err < 0) { + /* Error happened while encoding FFT coefficients. */ return err; } - /* complete arithmetic coding */ + /* Complete arithmetic coding. */ return WebRtcIsac_EncTerminate(bitStream); } - -int -WebRtcIsac_EncodeStoredDataUb16( - const ISACUBSaveEncDataStruct* ISACSavedEnc_obj, - Bitstr* bitStream, - WebRtc_Word32 jitterInfo, - float scale) -{ - int n; - int err; - double lpcGain[SUBFRAMES << 1]; - WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; - WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; - - /* reset bitstream */ - bitStream->W_upper = 0xFFFFFFFF; - bitStream->streamval = 0; - bitStream->stream_index = 0; - - // Encode jitter index - WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream); - - err = WebRtcIsac_EncodeBandwidth(isac16kHz, bitStream); - if(err < 0) - { - return err; - } - - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape, - WebRtcIsac_kLpcShapeCdfMatUb16, - UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); - - // we only consider scales between zero and one. - if((scale <= 0.0) || (scale > 1.0)) - { - scale = 1.0f; - } - - if(scale == 1.0f) - { - // store gains - WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex, - WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); - WebRtcIsac_EncHistMulti(bitStream, - &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES], - WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM); - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB16(ISACSavedEnc_obj->realFFT, - ISACSavedEnc_obj->imagFFT, bitStream); - } - else - { - /* Scale Gain */ - for(n = 0; n < SUBFRAMES; n++) - { - lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n]; - lpcGain[n + SUBFRAMES] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES]; - } - // store lpc gain - WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream); - WebRtcIsac_StoreLpcGainUb(&lpcGain[SUBFRAMES], bitStream); - /* scale FFT coefficients */ - for(n = 0; n < FRAMESAMPLES_HALF; n++) - { - realFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->realFFT[n] + - 0.5f); - imagFFT[n] = (WebRtc_Word16)(scale * (float)ISACSavedEnc_obj->imagFFT[n] + - 0.5f); - } - // store FFT coefficients - err = WebRtcIsac_EncodeSpecUB16(realFFT, imagFFT, bitStream); - } - - if(err < 0) - { - // error happened while encoding FFT coefficients. - return err; - } - - /* complete arithmetic coding */ - return WebRtcIsac_EncTerminate(bitStream); -} - - -WebRtc_Word16 -WebRtcIsac_GetRedPayloadUb( +WebRtc_Word16 WebRtcIsac_GetRedPayloadUb( const ISACUBSaveEncDataStruct* ISACSavedEncObj, Bitstr* bitStreamObj, - enum ISACBandwidth bandwidth) -{ + enum ISACBandwidth bandwidth) { int n; WebRtc_Word16 status; WebRtc_Word16 realFFT[FRAMESAMPLES_HALF]; WebRtc_Word16 imagFFT[FRAMESAMPLES_HALF]; - - // store bit-stream object. + enum ISACBand band; + const WebRtc_Word16 kAveragePitchGain = 0.0; + /* Store bit-stream object. */ memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr)); - // Scale FFT coefficients. - for(n = 0; n < FRAMESAMPLES_HALF; n++) - { + /* Scale FFT coefficients. */ + for (n = 0; n < FRAMESAMPLES_HALF; n++) { realFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->realFFT[n] * RCU_TRANSCODING_SCALE_UB + 0.5); imagFFT[n] = (WebRtc_Word16)((float)ISACSavedEncObj->imagFFT[n] * RCU_TRANSCODING_SCALE_UB + 0.5); } - switch(bandwidth) - { - case isac12kHz: - { - status = WebRtcIsac_EncodeSpecUB12(realFFT, imagFFT, bitStreamObj); - break; - } - case isac16kHz: - { - status = WebRtcIsac_EncodeSpecUB16(realFFT, imagFFT, bitStreamObj); - break; - } - default: - return -1; - } - - if(status < 0) - { - // error happened + band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16; + status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band, + bitStreamObj); + if (status < 0) { return status; - } - else - { - // terminate entropy coding + } else { + /* Terminate entropy coding */ return WebRtcIsac_EncTerminate(bitStreamObj); } } diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c b/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c index 5c7675f1f1..49c695ce2f 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c +++ b/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.c @@ -39,80 +39,80 @@ static const WebRtc_UWord16 kLpcVecPerSegmentUb16 = 4; /* CDF array for encoder bandwidth (12 vs 16 kHz) indicator. */ static const WebRtc_UWord16 kOneBitEqualProbCdf[3] = { - 0, 32768, 65535 }; + 0, 32768, 65535 }; /* Pointer to cdf array for encoder bandwidth (12 vs 16 kHz) indicator. */ -static const WebRtc_UWord16 *kOneBitEqualProbCdf_ptr[1] = { +static const WebRtc_UWord16* kOneBitEqualProbCdf_ptr[1] = { kOneBitEqualProbCdf }; /* * Initial cdf index for decoder of encoded bandwidth * (12 vs 16 kHz) indicator. */ -static const WebRtc_UWord16 kOneBitEqualProbInitIndex[1] = {1}; +static const WebRtc_UWord16 kOneBitEqualProbInitIndex[1] = { 1 }; -#define IS_SWB_12KHZ 1 + +static const int kIsSWB12 = 1; /* compute correlation from power spectrum */ -static void WebRtcIsac_FindCorrelation(WebRtc_Word32 *PSpecQ12, - WebRtc_Word32 *CorrQ7) -{ - WebRtc_Word32 summ[FRAMESAMPLES/8]; - WebRtc_Word32 diff[FRAMESAMPLES/8]; - const WebRtc_Word16 *CS_ptrQ9; +static void FindCorrelation(WebRtc_Word32* PSpecQ12, WebRtc_Word32* CorrQ7) { + WebRtc_Word32 summ[FRAMESAMPLES / 8]; + WebRtc_Word32 diff[FRAMESAMPLES / 8]; + const WebRtc_Word16* CS_ptrQ9; WebRtc_Word32 sum; int k, n; - for (k = 0; k < FRAMESAMPLES/8; k++) { - summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES_QUARTER-1 - k] + 16) >> 5; - diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES_QUARTER-1 - k] + 16) >> 5; + for (k = 0; k < FRAMESAMPLES / 8; k++) { + summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5; + diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5; } sum = 2; - for (n = 0; n < FRAMESAMPLES/8; n++) + for (n = 0; n < FRAMESAMPLES / 8; n++) { sum += summ[n]; + } CorrQ7[0] = sum; for (k = 0; k < AR_ORDER; k += 2) { sum = 0; CS_ptrQ9 = WebRtcIsac_kCos[k]; - for (n = 0; n < FRAMESAMPLES/8; n++) + for (n = 0; n < FRAMESAMPLES / 8; n++) sum += (CS_ptrQ9[n] * diff[n] + 256) >> 9; - CorrQ7[k+1] = sum; + CorrQ7[k + 1] = sum; } - for (k=1; k> 9; - CorrQ7[k+1] = sum; + CorrQ7[k + 1] = sum; } } /* compute inverse AR power spectrum */ /* Changed to the function used in iSAC FIX for compatibility reasons */ -static void WebRtcIsac_FindInvArSpec(const WebRtc_Word16 *ARCoefQ12, - const WebRtc_Word32 gainQ10, - WebRtc_Word32 *CurveQ16) -{ - WebRtc_Word32 CorrQ11[AR_ORDER+1]; +static void FindInvArSpec(const WebRtc_Word16* ARCoefQ12, + const WebRtc_Word32 gainQ10, + WebRtc_Word32* CurveQ16) { + WebRtc_Word32 CorrQ11[AR_ORDER + 1]; WebRtc_Word32 sum, tmpGain; - WebRtc_Word32 diffQ16[FRAMESAMPLES/8]; - const WebRtc_Word16 *CS_ptrQ9; + WebRtc_Word32 diffQ16[FRAMESAMPLES / 8]; + const WebRtc_Word16* CS_ptrQ9; int k, n; WebRtc_Word16 round, shftVal = 0, sh; sum = 0; - for (n = 0; n < AR_ORDER+1; n++) + for (n = 0; n < AR_ORDER + 1; n++) { sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */ + } sum = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(sum, 6), 65) + 32768, 16); /* Q8 */ CorrQ11[0] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, gainQ10) + 256, 9); /* To avoid overflow, we shift down gainQ10 if it is large. * We will not lose any precision */ - if(gainQ10>400000){ + if (gainQ10 > 400000) { tmpGain = WEBRTC_SPL_RSHIFT_W32(gainQ10, 3); round = 32; shftVal = 6; @@ -122,68 +122,66 @@ static void WebRtcIsac_FindInvArSpec(const WebRtc_Word16 *ARCoefQ12, shftVal = 9; } - for (k = 1; k < AR_ORDER+1; k++) { + for (k = 1; k < AR_ORDER + 1; k++) { sum = 16384; - for (n = k; n < AR_ORDER+1; n++) - sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ + for (n = k; n < AR_ORDER + 1; n++) + sum += WEBRTC_SPL_MUL(ARCoefQ12[n - k], ARCoefQ12[n]); /* Q24 */ sum = WEBRTC_SPL_RSHIFT_W32(sum, 15); CorrQ11[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(sum, tmpGain) + round, shftVal); } sum = WEBRTC_SPL_LSHIFT_W32(CorrQ11[0], 7); - for (n = 0; n < FRAMESAMPLES/8; n++) + for (n = 0; n < FRAMESAMPLES / 8; n++) { CurveQ16[n] = sum; - + } for (k = 1; k < AR_ORDER; k += 2) { - for (n = 0; n < FRAMESAMPLES/8; n++) - CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32( - WEBRTC_SPL_MUL(WebRtcIsac_kCos[k][n], CorrQ11[k+1]) + 2, 2); + for (n = 0; n < FRAMESAMPLES / 8; n++) { + CurveQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL( + WebRtcIsac_kCos[k][n], CorrQ11[k + 1]) + 2, 2); + } } CS_ptrQ9 = WebRtcIsac_kCos[0]; /* If CorrQ11[1] too large we avoid getting overflow in the * calculation by shifting */ - sh=WebRtcSpl_NormW32(CorrQ11[1]); - if (CorrQ11[1]==0) /* Use next correlation */ - sh=WebRtcSpl_NormW32(CorrQ11[2]); - - if (sh<9) + sh = WebRtcSpl_NormW32(CorrQ11[1]); + if (CorrQ11[1] == 0) { /* Use next correlation */ + sh = WebRtcSpl_NormW32(CorrQ11[2]); + } + if (sh < 9) { shftVal = 9 - sh; - else + } else { shftVal = 0; - - for (n = 0; n < FRAMESAMPLES/8; n++) + } + for (n = 0; n < FRAMESAMPLES / 8; n++) { diffQ16[n] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL( CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[1], shftVal)) + 2, 2); + } for (k = 2; k < AR_ORDER; k += 2) { CS_ptrQ9 = WebRtcIsac_kCos[k]; - for (n = 0; n < FRAMESAMPLES/8; n++) + for (n = 0; n < FRAMESAMPLES / 8; n++) { diffQ16[n] += WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL( - CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k+1], shftVal)) + 2, 2); + CS_ptrQ9[n], WEBRTC_SPL_RSHIFT_W32(CorrQ11[k + 1], shftVal)) + 2, 2); + } } - for (k=0; k> 25); shft = (seed >> 25) & 15; - if (shft < 5) - { + if (shft < 5) { bufQ7[k] = dither1_Q7; - bufQ7[k+1] = dither2_Q7; - bufQ7[k+2] = 0; - } - else if (shft < 10) - { + bufQ7[k + 1] = dither2_Q7; + bufQ7[k + 2] = 0; + } else if (shft < 10) { bufQ7[k] = dither1_Q7; - bufQ7[k+1] = 0; - bufQ7[k+2] = dither2_Q7; - } - else - { + bufQ7[k + 1] = 0; + bufQ7[k + 2] = dither2_Q7; + } else { bufQ7[k] = 0; - bufQ7[k+1] = dither1_Q7; - bufQ7[k+2] = dither2_Q7; + bufQ7[k + 1] = dither1_Q7; + bufQ7[k + 2] = dither2_Q7; } } - } - else - { + } else { dither_gain_Q14 = (WebRtc_Word16)(22528 - 10 * AvgPitchGain_Q12); /* Dither on half of the coefficients. */ - for (k = 0; k < length-1; k += 2) - { + for (k = 0; k < length - 1; k += 2) { /* New random unsigned int */ seed = (seed * 196314165) + 907633515; /* Fixed-point dither sample between -64 and 64. */ - dither1_Q7 = (WebRtc_Word16)(((int)seed + 16777216)>>25); + dither1_Q7 = (WebRtc_Word16)(((int)seed + 16777216) >> 25); /* Dither sample is placed in either even or odd index. */ shft = (seed >> 25) & 1; /* Either 0 or 1 */ - bufQ7[k + shft] = (((dither_gain_Q14 * dither1_Q7) + 8192)>>14); + bufQ7[k + shft] = (((dither_gain_Q14 * dither1_Q7) + 8192) >> 14); bufQ7[k + 1 - shft] = 0; } } @@ -259,10 +249,9 @@ static void GenerateDitherQ7Lb(WebRtc_Word16 *bufQ7, * -bufQ7 : pointer to a buffer where dithers are written to. */ static void GenerateDitherQ7LbUB( - WebRtc_Word16 *bufQ7, + WebRtc_Word16* bufQ7, WebRtc_UWord32 seed, - int length) -{ + int length) { int k; for (k = 0; k < length; k++) { /* new random unsigned int */ @@ -270,39 +259,43 @@ static void GenerateDitherQ7LbUB( /* Fixed-point dither sample between -64 and 64 (Q7). */ /* bufQ7 = seed * 128 / 4294967295 */ - bufQ7[k] = (WebRtc_Word16)(((int)seed + 16777216)>>25); + bufQ7[k] = (WebRtc_Word16)(((int)seed + 16777216) >> 25); /* Scale by 0.35. */ - bufQ7[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(bufQ7[k], - 2048, 13); + bufQ7[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(bufQ7[k], 2048, 13); } } - - /* * Function to decode the complex spectrum from the bit stream * returns the total number of bytes in the stream. */ -int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, - double *fr, - double *fi, - WebRtc_Word16 AvgPitchGain_Q12) -{ +int WebRtcIsac_DecodeSpec(Bitstr* streamdata, WebRtc_Word16 AvgPitchGain_Q12, + enum ISACBand band, double* fr, double* fi) { WebRtc_Word16 DitherQ7[FRAMESAMPLES]; WebRtc_Word16 data[FRAMESAMPLES]; WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; + WebRtc_Word16 ARCoefQ12[AR_ORDER + 1]; WebRtc_Word16 RCQ15[AR_ORDER]; WebRtc_Word16 gainQ10; WebRtc_Word32 gain2_Q10, res; WebRtc_Word32 in_sqrt; WebRtc_Word32 newRes; - int k, len, i; - + int k, len, i; + int is_12khz = !kIsSWB12; + int num_dft_coeff = FRAMESAMPLES; /* Create dither signal. */ - GenerateDitherQ7Lb(DitherQ7, streamdata->W_upper, FRAMESAMPLES, AvgPitchGain_Q12); + if (band == kIsacLowerBand) { + GenerateDitherQ7Lb(DitherQ7, streamdata->W_upper, FRAMESAMPLES, + AvgPitchGain_Q12); + } else { + GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES); + if (band == kIsacUpperBand12) { + is_12khz = kIsSWB12; + num_dft_coeff = FRAMESAMPLES_HALF; + } + } /* Decode model parameters. */ if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) @@ -314,23 +307,21 @@ int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; /* Compute inverse AR power spectrum. */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); + FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); /* Convert to magnitude spectrum, * by doing square-roots (modified from SPLIB). */ res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { + for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { in_sqrt = invARSpec2_Q16[k]; i = 10; /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; + if (in_sqrt < 0) + in_sqrt = -in_sqrt; newRes = (in_sqrt / res + res) >> 1; - do - { + do { res = newRes; newRes = (in_sqrt / res + res) >> 1; } while (newRes != res && i-- > 0); @@ -338,335 +329,216 @@ int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, invARSpecQ8[k] = (WebRtc_Word16)newRes; } + len = WebRtcIsac_DecLogisticMulti2(data, streamdata, invARSpecQ8, DitherQ7, + num_dft_coeff, is_12khz); /* Arithmetic decoding of spectrum. */ - if ((len = WebRtcIsac_DecLogisticMulti2( - data, streamdata, invARSpecQ8, DitherQ7, FRAMESAMPLES, - !IS_SWB_12KHZ)) <1) { + if (len < 1) { return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; } - /* subtract dither and scale down spectral samples with low SNR */ - if (AvgPitchGain_Q12 <= 614) - { - for (k = 0; k < FRAMESAMPLES; k += 4) - { - gainQ10 = WebRtcSpl_DivW32W16ResW16( - 30 << 10,(WebRtc_Word16)((invARSpec2_Q16[k >> 2] + - (32768 + (33 << 16))) >> 16)); - *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+1] * gainQ10 + 512) >> 10) / 128.0; - *fr++ = (double)((data[k+2] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+3] * gainQ10 + 512) >> 10) / 128.0; - } - } - else - { - for (k = 0; k < FRAMESAMPLES; k += 4) - { - gainQ10 = WebRtcSpl_DivW32W16ResW16( - 36 << 10, (WebRtc_Word16)((invARSpec2_Q16[k >> 2] + - (32768 + (40 << 16))) >> 16)); - *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+1] * gainQ10 + 512) >> 10) / 128.0; - *fr++ = (double)((data[k+2] * gainQ10 + 512) >> 10) / 128.0; - *fi++ = (double)((data[k+3] * gainQ10 + 512) >> 10) / 128.0; - } - } + switch (band) { + case kIsacLowerBand: { + /* Scale down spectral samples with low SNR. */ + WebRtc_Word32 p1; + WebRtc_Word32 p2; + if (AvgPitchGain_Q12 <= 614) { + p1 = 30 << 10; + p2 = 32768 + (33 << 16); + } else { + p1 = 36 << 10; + p2 = 32768 + (40 << 16); + } + for (k = 0; k < FRAMESAMPLES; k += 4) { + gainQ10 = WebRtcSpl_DivW32W16ResW16(p1, (WebRtc_Word16)( + (invARSpec2_Q16[k >> 2] + p2) >> 16)); + *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0; + *fi++ = (double)((data[k + 1] * gainQ10 + 512) >> 10) / 128.0; + *fr++ = (double)((data[k + 2] * gainQ10 + 512) >> 10) / 128.0; + *fi++ = (double)((data[k + 3] * gainQ10 + 512) >> 10) / 128.0; + } + break; + } + case kIsacUpperBand12: { + for (k = 0, i = 0; k < FRAMESAMPLES_HALF; k += 4) { + fr[i] = (double)data[ k ] / 128.0; + fi[i] = (double)data[k + 1] / 128.0; + i++; + fr[i] = (double)data[k + 2] / 128.0; + fi[i] = (double)data[k + 3] / 128.0; + i++; + } + /* The second half of real and imaginary coefficients is zero. This is + * due to using the old FFT module which requires two signals as input + * while in 0-12 kHz mode we only have 8-12 kHz band, and the second + * signal is set to zero. */ + memset(&fr[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * + sizeof(double)); + memset(&fi[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * + sizeof(double)); + break; + } + case kIsacUpperBand16: { + for (i = 0, k = 0; k < FRAMESAMPLES; k += 4, i++) { + fr[i] = (double)data[ k ] / 128.0; + fi[i] = (double)data[k + 1] / 128.0; + fr[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 2] / 128.0; + fi[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 3] / 128.0; + } + break; + } + } return len; } -/****************************************************************************** - * WebRtcIsac_DecodeSpecUB16() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). - * - * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB16( - Bitstr* streamdata, - double* fr, - double* fi) -{ - WebRtc_Word16 DitherQ7[FRAMESAMPLES]; - WebRtc_Word16 data[FRAMESAMPLES]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; + +int WebRtcIsac_EncodeSpec(const WebRtc_Word16* fr, const WebRtc_Word16* fi, + WebRtc_Word16 AvgPitchGain_Q12, enum ISACBand band, + Bitstr* streamdata) { + WebRtc_Word16 ditherQ7[FRAMESAMPLES]; + WebRtc_Word16 dataQ7[FRAMESAMPLES]; + WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; + WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word32 gain2_Q10, res; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - int k, len, i, j; + WebRtc_Word32 CorrQ7[AR_ORDER + 1]; + WebRtc_Word32 CorrQ7_norm[AR_ORDER + 1]; + WebRtc_Word16 RCQ15[AR_ORDER]; + WebRtc_Word16 ARCoefQ12[AR_ORDER + 1]; + WebRtc_Word32 gain2_Q10; + WebRtc_Word16 val; + WebRtc_Word32 nrg, res; + WebRtc_UWord32 sum; + WebRtc_Word32 in_sqrt; + WebRtc_Word32 newRes; + WebRtc_Word16 err; + WebRtc_UWord32 nrg_u32; + int shift_var; + int k, n, j, i; + int is_12khz = !kIsSWB12; + int num_dft_coeff = FRAMESAMPLES; /* Create dither signal. */ - GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* Decode model parameters. */ - if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - /* Compute inverse AR power spectrum. */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* Convert to magnitude spectrum, by doing square-roots - * (modified from SPLIB). */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; + if (band == kIsacLowerBand) { + GenerateDitherQ7Lb(ditherQ7, streamdata->W_upper, FRAMESAMPLES, + AvgPitchGain_Q12); + } else { + GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES); + if (band == kIsacUpperBand12) { + is_12khz = kIsSWB12; + num_dft_coeff = FRAMESAMPLES_HALF; + } } - /* arithmetic decoding of spectrum */ - if ((len = WebRtcIsac_DecLogisticMulti2( - data, streamdata, invARSpecQ8, DitherQ7, - FRAMESAMPLES, !IS_SWB_12KHZ)) <1) { - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - } - - /* re-arrange DFT coefficients and scale down */ - for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) - { - fr[j] = (double)data[ k ] / 128.0; - fi[j] = (double)data[k+1] / 128.0; - fr[(FRAMESAMPLES_HALF) - 1 - j] = (double)data[k+2] / 128.0; - fi[(FRAMESAMPLES_HALF) - 1 - j] = (double)data[k+3] / 128.0; - - } - return len; -} - - - - -/****************************************************************************** - * WebRtcIsac_DecodeSpecUB12() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-12 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). - * - * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB12( - Bitstr *streamdata, - double *fr, - double *fi) -{ - WebRtc_Word16 DitherQ7[FRAMESAMPLES]; - WebRtc_Word16 data[FRAMESAMPLES]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word32 res; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - int k, len, i; - - /* Create dither signal */ - GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* Decode model parameters */ - if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0) - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - - - /* Compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* Convert to magnitude spectrum, by doing square-roots - * (modified from SPLIB). */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic decoding of spectrum */ - if ((len = WebRtcIsac_DecLogisticMulti2( - data, streamdata, invARSpecQ8, DitherQ7, (FRAMESAMPLES_HALF), - IS_SWB_12KHZ)) < 1) { - return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; - } - - for (k = 0, i = 0; k < FRAMESAMPLES_HALF; k += 4) - { - fr[i] = (double)data[ k ] / 128.0; - fi[i] = (double)data[k+1] / 128.0; - i++; - fr[i] = (double)data[k+2] / 128.0; - fi[i] = (double)data[k+3] / 128.0; - i++; - } - - /* - * The second half of real and imaginary coefficients is zero. This is - * due to using the old FFT module which requires two signals as input - * while in 0-12 kHz mode we only have 8-12 kHz band, and the second signal - * is set to zero - */ - memset(&fr[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * sizeof(double)); - memset(&fi[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER * sizeof(double)); - return len; -} - - - - - -int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16 *fr, - const WebRtc_Word16 *fi, - Bitstr *streamdata, - WebRtc_Word16 AvgPitchGain_Q12) -{ - WebRtc_Word16 ditherQ7[FRAMESAMPLES]; - WebRtc_Word16 dataQ7[FRAMESAMPLES]; - WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 CorrQ7[AR_ORDER+1]; - WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word16 val; - WebRtc_Word32 nrg, res; - WebRtc_UWord32 sum; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - WebRtc_Word16 err; - WebRtc_UWord32 nrg_u32; - int shift_var; - int k, n, j, i; - - - /* create dither_float signal */ - GenerateDitherQ7Lb(ditherQ7, streamdata->W_upper, FRAMESAMPLES, - AvgPitchGain_Q12); - /* add dither and quantize, and compute power spectrum */ - for (k = 0; k < FRAMESAMPLES; k += 4) - { - val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; - dataQ7[k] = val; - sum = val * val; + switch (band) { + case kIsacLowerBand: { + for (k = 0; k < FRAMESAMPLES; k += 4) { + val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; + dataQ7[k] = val; + sum = val * val; - val = ((*fi++ + ditherQ7[k+1] + 64) & 0xFF80) - ditherQ7[k+1]; - dataQ7[k+1] = val; - sum += val * val; + val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1]; + dataQ7[k + 1] = val; + sum += val * val; - val = ((*fr++ + ditherQ7[k+2] + 64) & 0xFF80) - ditherQ7[k+2]; - dataQ7[k+2] = val; - sum += val * val; + val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2]; + dataQ7[k + 2] = val; + sum += val * val; - val = ((*fi++ + ditherQ7[k+3] + 64) & 0xFF80) - ditherQ7[k+3]; - dataQ7[k+3] = val; - sum += val * val; + val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3]; + dataQ7[k + 3] = val; + sum += val * val; - PSpec[k>>2] = sum >> 2; + PSpec[k >> 2] = sum >> 2; + } + break; + } + case kIsacUpperBand12: { + for (k = 0, j = 0; k < FRAMESAMPLES_HALF; k += 4) { + val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; + dataQ7[k] = val; + sum = val * val; + + val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1]; + dataQ7[k + 1] = val; + sum += val * val; + + PSpec[j++] = sum >> 1; + + val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2]; + dataQ7[k + 2] = val; + sum = val * val; + + val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3]; + dataQ7[k + 3] = val; + sum += val * val; + + PSpec[j++] = sum >> 1; + } + break; + } + case kIsacUpperBand16: { + for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) { + val = ((fr[j] + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; + dataQ7[k] = val; + sum = val * val; + + val = ((fi[j] + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1]; + dataQ7[k + 1] = val; + sum += val * val; + + val = ((fr[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 2] + 64) & + 0xFF80) - ditherQ7[k + 2]; + dataQ7[k + 2] = val; + sum += val * val; + + val = ((fi[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 3] + 64) & + 0xFF80) - ditherQ7[k + 3]; + dataQ7[k + 3] = val; + sum += val * val; + + PSpec[k >> 2] = sum >> 2; + } + break; + } } /* compute correlation from power spectrum */ - WebRtcIsac_FindCorrelation(PSpec, CorrQ7); + FindCorrelation(PSpec, CorrQ7); - - /* find AR coefficients. */ - /* number of bit shifts to 14-bit normalize CorrQ7[0] + /* Find AR coefficients */ + /* Aumber of bit shifts to 14-bit normalize CorrQ7[0] * (leaving room for sign) */ shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; if (shift_var > 0) { - for (k=0; k> (-shift_var); } } - /* find RC coefficients */ + /* Find RC coefficients. */ WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); - /* quantize & code RC Coefficient */ + /* Quantize & code RC Coefficient. */ WebRtcIsac_EncodeRc(RCQ15, streamdata); /* RC -> AR coefficients */ WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - /* compute ARCoef' * Corr * ARCoef in Q19 */ + /* Compute ARCoef' * Corr * ARCoef in Q19. */ nrg = 0; for (j = 0; j <= AR_ORDER; j++) { for (n = 0; n <= j; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[j-n] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3; + nrg += (ARCoefQ12[j] * ((CorrQ7_norm[j - n] * ARCoefQ12[n] + 256) >> 9) + + 4) >> 3; } - for (n = j+1; n <= AR_ORDER; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + 256) >> 9) + 4 ) >> 3; + for (n = j + 1; n <= AR_ORDER; n++) { + nrg += (ARCoefQ12[j] * ((CorrQ7_norm[n - j] * ARCoefQ12[n] + 256) >> 9) + + 4) >> 3; } } @@ -676,422 +548,82 @@ int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16 *fr, } else { nrg_u32 = nrg_u32 << (-shift_var); } - - if (nrg_u32 > 0x7FFFFFFF) - nrg = 0x7FFFFFFF; - else - nrg = (WebRtc_Word32)nrg_u32; - - gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); /* also shifts 31 bits to the left! */ - - /* quantize & code gain2_Q10 */ - if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { - return -1; - } - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic coding of spectrum */ - err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, - FRAMESAMPLES, !IS_SWB_12KHZ); - if (err < 0) - { - return (err); - } - - return 0; -} - - -/****************************************************************************** - * WebRtcIsac_EncodeSpecUB16() - * Quantize and encode real and imaginary part of the DFT coefficients. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The real and imaginary part are computed by calling WebRtcIsac_Time2Spec(). - * - * - * Input: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are stored. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are stored. - * - * Output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_EncodeSpecUB16( - const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata) -{ - WebRtc_Word16 ditherQ7[FRAMESAMPLES]; - WebRtc_Word16 dataQ7[FRAMESAMPLES]; - WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 CorrQ7[AR_ORDER+1]; - WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word16 val; - WebRtc_Word32 nrg, res; - WebRtc_UWord32 sum; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - WebRtc_Word16 err; - WebRtc_UWord32 nrg_u32; - int shift_var; - int k, n, j, i; - - /* create dither_float signal */ - GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* add dither and quantize, and compute power spectrum */ - for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) - { - val = ((fr[j] + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; - dataQ7[k] = val; - sum = val * val; - - val = ((fi[j] + ditherQ7[k+1] + 64) & 0xFF80) - ditherQ7[k+1]; - dataQ7[k+1] = val; - sum += val * val; - - val = ((fr[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k+2] + 64) & - 0xFF80) - ditherQ7[k+2]; - dataQ7[k+2] = val; - sum += val * val; - - val = ((fi[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k+3] + 64) & - 0xFF80) - ditherQ7[k+3]; - dataQ7[k+3] = val; - sum += val * val; - - PSpec[k>>2] = sum >> 2; - } - - /* compute correlation from power spectrum */ - WebRtcIsac_FindCorrelation(PSpec, CorrQ7); - - - /* find AR coefficients - number of bit shifts to 14-bit normalize CorrQ7[0] - (leaving room for sign) */ - shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; - - if (shift_var > 0) { - for (k=0; k> (-shift_var); - } - } - - /* find RC coefficients */ - WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); - - /* quantize & code RC Coef */ - WebRtcIsac_EncodeRc(RCQ15, streamdata); - - /* RC -> AR coefficients */ - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - /* compute ARCoef' * Corr * ARCoef in Q19 */ - nrg = 0; - for (j = 0; j <= AR_ORDER; j++) { - for (n = 0; n <= j; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[j-n] * ARCoefQ12[n] + - 256) >> 9) + 4 ) >> 3; - } - for (n = j+1; n <= AR_ORDER; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + - 256) >> 9) + 4 ) >> 3; - } - } - nrg_u32 = (WebRtc_UWord32)nrg; - if (shift_var > 0) { - nrg_u32 = nrg_u32 >> shift_var; - } else { - nrg_u32 = nrg_u32 << (-shift_var); - } - - if (nrg_u32 > 0x7FFFFFFF) - nrg = 0x7FFFFFFF; - else - nrg = (WebRtc_Word32)nrg_u32; - /* also shifts 31 bits to the left! */ - gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); - - /* quantize & code gain2_Q10 */ - if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { - return -1; - } - - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots - * (modified from SPLIB) */ - res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { - in_sqrt = invARSpec2_Q16[k]; - i = 10; - - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - - newRes = (in_sqrt / res + res) >> 1; - do - { - res = newRes; - newRes = (in_sqrt / res + res) >> 1; - } while (newRes != res && i-- > 0); - - invARSpecQ8[k] = (WebRtc_Word16)newRes; - } - - /* arithmetic coding of spectrum */ - err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, - FRAMESAMPLES, !IS_SWB_12KHZ); - if (err < 0) - { - return (err); - } - - return 0; -} - - - - -int WebRtcIsac_EncodeSpecUB12(const WebRtc_Word16 *fr, - const WebRtc_Word16 *fi, - Bitstr *streamdata) -{ - WebRtc_Word16 ditherQ7[FRAMESAMPLES]; - WebRtc_Word16 dataQ7[FRAMESAMPLES]; - WebRtc_Word32 PSpec[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 invARSpec2_Q16[FRAMESAMPLES_QUARTER]; - WebRtc_UWord16 invARSpecQ8[FRAMESAMPLES_QUARTER]; - WebRtc_Word32 CorrQ7[AR_ORDER+1]; - WebRtc_Word32 CorrQ7_norm[AR_ORDER+1]; - WebRtc_Word16 RCQ15[AR_ORDER]; - WebRtc_Word16 ARCoefQ12[AR_ORDER+1]; - WebRtc_Word32 gain2_Q10; - WebRtc_Word16 val; - WebRtc_Word32 nrg, res; - WebRtc_UWord32 sum; - WebRtc_Word32 in_sqrt; - WebRtc_Word32 newRes; - WebRtc_Word16 err; - int shift_var; - int k, n, j, i; - WebRtc_UWord32 nrg_u32; - - /* create dither_float signal */ - GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES); - - /* add dither and quantize, and compute power spectrum */ - for (k = 0, j = 0; k < (FRAMESAMPLES_HALF); k += 4) - { - val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k]; - dataQ7[k] = val; - sum = (val) * (val); - - val = ((*fi++ + ditherQ7[k+1] + 64) & 0xFF80) - ditherQ7[k+1]; - dataQ7[k+1] = val; - sum += (val) * (val); - - if(j < FRAMESAMPLES_QUARTER) - { - PSpec[j] = sum >> 1; - j++; - } - - val = ((*fr++ + ditherQ7[k+2] + 64) & 0xFF80) - ditherQ7[k+2]; - dataQ7[k+2] = val; - sum = (val) * (val); - - val = ((*fi++ + ditherQ7[k+3] + 64) & 0xFF80) - ditherQ7[k+3]; - dataQ7[k+3] = val; - sum += (val) * (val); - - if(j < FRAMESAMPLES_QUARTER) - { - PSpec[j] = sum >> 1; - j++; - } - } - /* compute correlation from power spectrum */ - WebRtcIsac_FindCorrelation(PSpec, CorrQ7); - - - /* find AR coefficients */ - /* number of bit shifts to 14-bit normalize CorrQ7[0] - * (leaving room for sign) */ - shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18; - - if (shift_var > 0) { - for (k=0; k> (-shift_var); - } - } - - /* find RC coefficients */ - WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15); - - /* quantize & code RC Coef */ - WebRtcIsac_EncodeRc(RCQ15, streamdata); - - - /* RC -> AR coefficients */ - WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12); - - - /* compute ARCoef' * Corr * ARCoef in Q19 */ - nrg = 0; - for (j = 0; j <= AR_ORDER; j++) { - for (n = 0; n <= j; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[j-n] * ARCoefQ12[n] + 256) >> 9) + - 4 ) >> 3; - } - for (n = j+1; n <= AR_ORDER; n++) { - nrg += ( ARCoefQ12[j] * ((CorrQ7_norm[n-j] * ARCoefQ12[n] + 256) >> 9) + - 4 ) >> 3; - } - } - - nrg_u32 = (WebRtc_UWord32)nrg; - if (shift_var > 0) { - nrg_u32 = nrg_u32 >> shift_var; - } else { - nrg_u32 = nrg_u32 << (-shift_var); - } - if (nrg_u32 > 0x7FFFFFFF) { nrg = 0x7FFFFFFF; - } else { + } else { nrg = (WebRtc_Word32)nrg_u32; } - /* also shifts 31 bits to the left! */ + /* Also shifts 31 bits to the left! */ gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg); - /* quantize & code gain2_Q10 */ + /* Quantize & code gain2_Q10. */ if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) { return -1; } - /* compute inverse AR power spectrum */ - WebRtcIsac_FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); - - /* convert to magnitude spectrum, by doing square-roots - * (modified from SPLIB) */ + /* Compute inverse AR power spectrum. */ + FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16); + /* Convert to magnitude spectrum, by doing square-roots + * (modified from SPLIB). */ res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1); - for (k = 0; k < FRAMESAMPLES_QUARTER; k++) - { + for (k = 0; k < FRAMESAMPLES_QUARTER; k++) { in_sqrt = invARSpec2_Q16[k]; i = 10; - /* Negative values make no sense for a real sqrt-function. */ - if (in_sqrt<0) - in_sqrt=-in_sqrt; - + if (in_sqrt < 0) { + in_sqrt = -in_sqrt; + } newRes = (in_sqrt / res + res) >> 1; - do - { + do { res = newRes; newRes = (in_sqrt / res + res) >> 1; } while (newRes != res && i-- > 0); invARSpecQ8[k] = (WebRtc_Word16)newRes; } - /* arithmetic coding of spectrum */ err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8, - (FRAMESAMPLES_HALF), IS_SWB_12KHZ); - if (err < 0) - { + num_dft_coeff, is_12khz); + if (err < 0) { return (err); } - return 0; } - /* step-up */ -void WebRtcIsac_Rc2Poly(double *RC, int N, double *a) -{ +void WebRtcIsac_Rc2Poly(double* RC, int N, double* a) { int m, k; double tmp[MAX_AR_MODEL_ORDER]; a[0] = 1.0; tmp[0] = 1.0; - for (m=1; m<=N; m++) { + for (m = 1; m <= N; m++) { /* copy */ - for (k=1; k0; m--) { - tmp_inv = 1.0 / (1.0 - RC[m]*RC[m]); - for (k=1; k<=m; k++) - tmp[k] = (a[k] - RC[m] * a[m-k+1]) * tmp_inv; + RC[N - 1] = a[N]; + for (m = N - 1; m > 0; m--) { + tmp_inv = 1.0 / (1.0 - RC[m] * RC[m]); + for (k = 1; k <= m; k++) { + tmp[k] = (a[k] - RC[m] * a[m - k + 1]) * tmp_inv; + } - for (k=1; k WebRtcIsac_kQKltMaxIndShape[k]) + } else if (index_s[k] > WebRtcIsac_kQKltMaxIndShape[k]) { index_s[k] = WebRtcIsac_kQKltMaxIndShape[k]; - index_ovr_s[k] = WebRtcIsac_kQKltOffsetShape[k]+index_s[k]; + } + index_ovr_s[k] = WebRtcIsac_kQKltOffsetShape[k] + index_s[k]; } @@ -1599,33 +1085,33 @@ void WebRtcIsac_EncodeLar(double *LPCCoef, Bitstr *streamdata, /* entropy coding of model number */ WebRtcIsac_EncHistMulti(streamdata, &kModel, WebRtcIsac_kQKltModelCdfPtr, 1); - + /* Save data for creation of multiple bit streams */ /* Entropy coding of quantization indices - shape only. */ WebRtcIsac_EncHistMulti(streamdata, index_s, WebRtcIsac_kQKltCdfPtrShape, KLT_ORDER_SHAPE); /* Save data for creation of multiple bit streams. */ - for (k=0; kLPCindex_s[KLT_ORDER_SHAPE*encData->startIdx + k] = index_s[k]; + for (k = 0; k < KLT_ORDER_SHAPE; k++) { + encData->LPCindex_s[KLT_ORDER_SHAPE * encData->startIdx + k] = index_s[k]; } /* Find quantization levels for shape coefficients. */ - for (k=0; kLPCcoeffs_lo[(ORDERLO+1)*SUBFRAMES*encData->startIdx + k] = + for (k = 0; k < (ORDERLO + 1)*SUBFRAMES; k++) { + encData->LPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * encData->startIdx + k] = LPCCoef_lo[k]; } - for (k=0; k<(ORDERHI+1)*SUBFRAMES; k++) { - encData->LPCcoeffs_hi[(ORDERHI+1)*SUBFRAMES*encData->startIdx + k] = + for (k = 0; k < (ORDERHI + 1)*SUBFRAMES; k++) { + encData->LPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * encData->startIdx + k] = LPCCoef_hi[k]; } } -WebRtc_Word16 -WebRtcIsac_EncodeLpcUB( - double* lpcVecs, - Bitstr* streamdata, - double* interpolLPCCoeff, - WebRtc_Word16 bandwidth, - ISACUBSaveEncDataStruct* encData) -{ - +WebRtc_Word16 WebRtcIsac_EncodeLpcUB(double* lpcVecs, Bitstr* streamdata, + double* interpolLPCCoeff, + WebRtc_Word16 bandwidth, + ISACUBSaveEncDataStruct* encData) { double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; int idx[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; int interpolCntr; @@ -1719,50 +1199,45 @@ WebRtcIsac_EncodeLpcUB( WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth); WebRtcIsac_AddLarMean(lpcVecs, bandwidth); - switch(bandwidth) - { - case isac12kHz: - { - /* Store the indices to be used for multiple encoding. */ - memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * - UB_LPC_VEC_PER_FRAME * sizeof(int)); - WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb12, - UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); - for(interpolCntr = 0; interpolCntr < UB_INTERPOL_SEGMENTS; - interpolCntr++) - { - WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff, - kLpcVecPerSegmentUb12 + 1); - lpcVecs += UB_LPC_ORDER; - interpolLPCCoeff += (kLpcVecPerSegmentUb12 * (UB_LPC_ORDER + 1)); - } - break; + switch (bandwidth) { + case isac12kHz: { + /* Store the indices to be used for multiple encoding. */ + memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * + UB_LPC_VEC_PER_FRAME * sizeof(int)); + WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb12, + UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME); + for (interpolCntr = 0; interpolCntr < UB_INTERPOL_SEGMENTS; + interpolCntr++) { + WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff, + kLpcVecPerSegmentUb12 + 1); + lpcVecs += UB_LPC_ORDER; + interpolLPCCoeff += (kLpcVecPerSegmentUb12 * (UB_LPC_ORDER + 1)); } - case isac16kHz: - { - /* Store the indices to be used for multiple encoding. */ - memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * - UB16_LPC_VEC_PER_FRAME * sizeof(int)); - WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb16, - UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); - for(interpolCntr = 0; interpolCntr < UB16_INTERPOL_SEGMENTS; - interpolCntr++) - { - WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff, - kLpcVecPerSegmentUb16 + 1); - lpcVecs += UB_LPC_ORDER; - interpolLPCCoeff += (kLpcVecPerSegmentUb16 * (UB_LPC_ORDER + 1)); - } - break; + break; + } + case isac16kHz: { + /* Store the indices to be used for multiple encoding. */ + memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER * + UB16_LPC_VEC_PER_FRAME * sizeof(int)); + WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb16, + UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME); + for (interpolCntr = 0; interpolCntr < UB16_INTERPOL_SEGMENTS; + interpolCntr++) { + WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff, + kLpcVecPerSegmentUb16 + 1); + lpcVecs += UB_LPC_ORDER; + interpolLPCCoeff += (kLpcVecPerSegmentUb16 * (UB_LPC_ORDER + 1)); } + break; + } default: return -1; } return 0; } -void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, - Bitstr *streamdata, +void WebRtcIsac_EncodeLpcGainLb(double* LPCCoef_lo, double* LPCCoef_hi, + Bitstr* streamdata, ISAC_SaveEncData_t* encData) { int j, k, n, pos, pos2, posg, offsg, offs2; int index_g[KLT_ORDER_GAIN]; @@ -1772,12 +1247,12 @@ void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, double sum; /* log gains, mean removal and scaling */ posg = 0; - for (k=0; k WebRtcIsac_kQKltMaxIndGain[k]) { + } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) { index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; } - index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k]+index_g[k]; + index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k]; /* Find quantization levels for coefficients. */ tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]]; /* Save data for creation of multiple bit streams. */ - encData->LPCindex_g[KLT_ORDER_GAIN*encData->startIdx + k] = index_g[k]; + encData->LPCindex_g[KLT_ORDER_GAIN * encData->startIdx + k] = index_g[k]; } /* Entropy coding of quantization indices - gain. */ @@ -1849,13 +1323,13 @@ void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, /* Left transform. */ offsg = 0; posg = 0; - for (j=0; j WebRtcIsac_kQArBoundaryLevels[index[k]]) - { - while (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k] + 1]) + if (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k]]) { + while (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k] + 1]) { index[k]++; - } - else - { + } + } else { while (RCQ15[k] < WebRtcIsac_kQArBoundaryLevels[--index[k]]) ; } RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]); @@ -2010,38 +1466,33 @@ void WebRtcIsac_EncodeRc(WebRtc_Word16 *RCQ15, Bitstr *streamdata) /* decode & dequantize squared Gain */ -int WebRtcIsac_DecodeGain2(Bitstr *streamdata, WebRtc_Word32 *gainQ10) -{ +int WebRtcIsac_DecodeGain2(Bitstr* streamdata, WebRtc_Word32* gainQ10) { int index, err; /* entropy decoding of quantization index */ err = WebRtcIsac_DecHistOneStepMulti(&index, streamdata, WebRtcIsac_kQGainCdf_ptr, WebRtcIsac_kQGainInitIndex, 1); - if (err<0) + if (err < 0) { return err; - + } /* find quantization level */ *gainQ10 = WebRtcIsac_kQGain2Levels[index]; return 0; } - /* quantize & code squared Gain */ -int WebRtcIsac_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr *streamdata) -{ +int WebRtcIsac_EncodeGain2(WebRtc_Word32* gainQ10, Bitstr* streamdata) { int index; /* find quantization index */ index = WebRtcIsac_kQGainInitIndex[0]; - if (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index]) - { - while (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index + 1]) + if (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index]) { + while (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index + 1]) { index++; - } - else - { + } + } else { while (*gainQ10 < WebRtcIsac_kQGain2BoundaryLevels[--index]) ; } /* De-quantize */ @@ -2056,11 +1507,10 @@ int WebRtcIsac_EncodeGain2(WebRtc_Word32 *gainQ10, Bitstr *streamdata) /* code and decode Pitch Gains and Lags functions */ /* decode & dequantize Pitch Gains */ -int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, - WebRtc_Word16 *PitchGains_Q12) -{ +int WebRtcIsac_DecodePitchGain(Bitstr* streamdata, + WebRtc_Word16* PitchGains_Q12) { int index_comb, err; - const WebRtc_UWord16 *WebRtcIsac_kQPitchGainCdf_ptr[1]; + const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1]; /* Entropy decoding of quantization indices */ *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf; @@ -2068,9 +1518,9 @@ int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, WebRtcIsac_kQPitchGainCdf_ptr, WebRtcIsac_kQCdfTableSizeGain, 1); /* Error check, Q_mean_Gain.. tables are of size 144 */ - if ((err<0) || (index_comb<0) || (index_comb>144)) + if ((err < 0) || (index_comb < 0) || (index_comb > 144)) { return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN; - + } /* De-quantize back to pitch gains by table look-up. */ PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb]; PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb]; @@ -2081,33 +1531,31 @@ int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, /* Quantize & code Pitch Gains. */ -void WebRtcIsac_EncodePitchGain(WebRtc_Word16 *PitchGains_Q12, - Bitstr *streamdata, +void WebRtcIsac_EncodePitchGain(WebRtc_Word16* PitchGains_Q12, + Bitstr* streamdata, ISAC_SaveEncData_t* encData) { - int k,j; + int k, j; double C; double S[PITCH_SUBFRAMES]; int index[3]; int index_comb; - const WebRtc_UWord16 *WebRtcIsac_kQPitchGainCdf_ptr[1]; - double PitchGains[PITCH_SUBFRAMES] = {0,0,0,0}; + const WebRtc_UWord16* WebRtcIsac_kQPitchGainCdf_ptr[1]; + double PitchGains[PITCH_SUBFRAMES] = {0, 0, 0, 0}; /* Take the asin. */ - for (k=0; k upper_limit[k]) index[k] = upper_limit[k]; - index[k] -= lower_limit[k]; - + if (index[k] < lower_limit[k]) { + index[k] = lower_limit[k]; + } else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; { + index[k] -= lower_limit[k]; + } /* Save data for creation of multiple bit streams */ - encData->pitchIndex[PITCH_SUBFRAMES*encData->startIdx + k] = index[k]; + encData->pitchIndex[PITCH_SUBFRAMES * encData->startIdx + k] = index[k]; } /* Un-quantize back to transform coefficients and do the inverse transform: * S = T'*C */ C = (index[0] + lower_limit[0]) * StepSize; - for (k=0; k WebRtcIsac_kQKltMaxIndGain[k]) { + } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) { index_g[k] = WebRtcIsac_kQKltMaxIndGain[k]; } - index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k]+index_g[k]; + index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k]; /* find quantization levels for coefficients */ tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]]; @@ -2505,43 +1948,35 @@ void WebRtcIsac_TranscodeLPCCoef(double *LPCCoef_lo, double *LPCCoef_hi, /* Decode & de-quantize LPC Coefficients. */ -int -WebRtcIsac_DecodeLpcCoefUB( - Bitstr* streamdata, - double* lpcVecs, - double* percepFilterGains, - WebRtc_Word16 bandwidth) -{ +int WebRtcIsac_DecodeLpcCoefUB(Bitstr* streamdata, double* lpcVecs, + double* percepFilterGains, + WebRtc_Word16 bandwidth) { int index_s[KLT_ORDER_SHAPE]; double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME]; int err; /* Entropy decoding of quantization indices. */ - switch(bandwidth) - { - case isac12kHz: - { - err = WebRtcIsac_DecHistOneStepMulti( - index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb12, - WebRtcIsac_kLpcShapeEntropySearchUb12, UB_LPC_ORDER * - UB_LPC_VEC_PER_FRAME); - break; - } - case isac16kHz: - { - err = WebRtcIsac_DecHistOneStepMulti( - index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb16, - WebRtcIsac_kLpcShapeEntropySearchUb16, UB_LPC_ORDER * - UB16_LPC_VEC_PER_FRAME); - break; - } + switch (bandwidth) { + case isac12kHz: { + err = WebRtcIsac_DecHistOneStepMulti( + index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb12, + WebRtcIsac_kLpcShapeEntropySearchUb12, UB_LPC_ORDER * + UB_LPC_VEC_PER_FRAME); + break; + } + case isac16kHz: { + err = WebRtcIsac_DecHistOneStepMulti( + index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb16, + WebRtcIsac_kLpcShapeEntropySearchUb16, UB_LPC_ORDER * + UB16_LPC_VEC_PER_FRAME); + break; + } default: return -1; } - if (err<0) - { + if (err < 0) { return err; } @@ -2551,108 +1986,79 @@ WebRtcIsac_DecodeLpcCoefUB( WebRtcIsac_AddLarMean(lpcVecs, bandwidth); WebRtcIsac_DecodeLpcGainUb(percepFilterGains, streamdata); - if(bandwidth == isac16kHz) - { + if (bandwidth == isac16kHz) { /* Decode another set of Gains. */ WebRtcIsac_DecodeLpcGainUb(&percepFilterGains[SUBFRAMES], streamdata); } - return 0; } -WebRtc_Word16 -WebRtcIsac_EncodeBandwidth( - enum ISACBandwidth bandwidth, - Bitstr* streamData) -{ +WebRtc_Word16 WebRtcIsac_EncodeBandwidth(enum ISACBandwidth bandwidth, + Bitstr* streamData) { int bandwidthMode; - switch(bandwidth) - { - case isac12kHz: - { - bandwidthMode = 0; - break; - } - case isac16kHz: - { - bandwidthMode = 1; - break; - } + switch (bandwidth) { + case isac12kHz: { + bandwidthMode = 0; + break; + } + case isac16kHz: { + bandwidthMode = 1; + break; + } default: return -ISAC_DISALLOWED_ENCODER_BANDWIDTH; } - - WebRtcIsac_EncHistMulti(streamData, &bandwidthMode, - kOneBitEqualProbCdf_ptr, 1); + WebRtcIsac_EncHistMulti(streamData, &bandwidthMode, kOneBitEqualProbCdf_ptr, + 1); return 0; } -WebRtc_Word16 -WebRtcIsac_DecodeBandwidth( - Bitstr* streamData, - enum ISACBandwidth* bandwidth) -{ +WebRtc_Word16 WebRtcIsac_DecodeBandwidth(Bitstr* streamData, + enum ISACBandwidth* bandwidth) { int bandwidthMode; - - if(WebRtcIsac_DecHistOneStepMulti(&bandwidthMode, streamData, - kOneBitEqualProbCdf_ptr, - kOneBitEqualProbInitIndex, 1) < 0) - { + if (WebRtcIsac_DecHistOneStepMulti(&bandwidthMode, streamData, + kOneBitEqualProbCdf_ptr, + kOneBitEqualProbInitIndex, 1) < 0) { return -ISAC_RANGE_ERROR_DECODE_BANDWITH; } - - switch(bandwidthMode) - { - case 0: - { - *bandwidth = isac12kHz; - break; - } - case 1: - { - *bandwidth = isac16kHz; - break; - } + switch (bandwidthMode) { + case 0: { + *bandwidth = isac12kHz; + break; + } + case 1: { + *bandwidth = isac16kHz; + break; + } default: return -ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER; } return 0; } -WebRtc_Word16 -WebRtcIsac_EncodeJitterInfo( - WebRtc_Word32 jitterIndex, - Bitstr* streamData) -{ +WebRtc_Word16 WebRtcIsac_EncodeJitterInfo(WebRtc_Word32 jitterIndex, + Bitstr* streamData) { /* This is to avoid LINUX warning until we change 'int' to 'Word32'. */ int intVar; - if((jitterIndex < 0) || (jitterIndex > 1)) - { + if ((jitterIndex < 0) || (jitterIndex > 1)) { return -1; } intVar = (int)(jitterIndex); /* Use the same CDF table as for bandwidth * both take two values with equal probability.*/ - WebRtcIsac_EncHistMulti(streamData, &intVar, - kOneBitEqualProbCdf_ptr, 1); + WebRtcIsac_EncHistMulti(streamData, &intVar, kOneBitEqualProbCdf_ptr, 1); return 0; - } -WebRtc_Word16 -WebRtcIsac_DecodeJitterInfo( - Bitstr* streamData, - WebRtc_Word32* jitterInfo) -{ +WebRtc_Word16 WebRtcIsac_DecodeJitterInfo(Bitstr* streamData, + WebRtc_Word32* jitterInfo) { int intVar; - /* Use the same CDF table as for bandwidth * both take two values with equal probability. */ - if(WebRtcIsac_DecHistOneStepMulti(&intVar, streamData, - kOneBitEqualProbCdf_ptr, - kOneBitEqualProbInitIndex, 1) < 0) - { + if (WebRtcIsac_DecHistOneStepMulti(&intVar, streamData, + kOneBitEqualProbCdf_ptr, + kOneBitEqualProbInitIndex, 1) < 0) { return -ISAC_RANGE_ERROR_DECODE_BANDWITH; } *jitterInfo = (WebRtc_Word16)(intVar); diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.h b/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.h index 44dce6d5b7..1a469535ad 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.h +++ b/src/modules/audio_coding/codecs/iSAC/main/source/entropy_coding.h @@ -19,18 +19,12 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ +#include "settings.h" #include "structs.h" -/* decode complex spectrum (return number of bytes in stream) */ -int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, - double *fr, - double *fi, - WebRtc_Word16 AvgPitchGain_Q12); - /****************************************************************************** - * WebRtcIsac_DecodeSpecUB16() + * WebRtcIsac_DecodeSpec() * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-16 kHz bandwidth. * The decoded DFT coefficient can be transformed to time domain by * WebRtcIsac_Time2Spec(). * @@ -38,68 +32,37 @@ int WebRtcIsac_DecodeSpecLb(Bitstr *streamdata, * - streamdata : pointer to a stucture containg the encoded * data and theparameters needed for entropy * coding. + * - AvgPitchGain_Q12 : average pitch-gain of the frame. This is only + * relevant for 0-4 kHz band, and the input value is + * not used in other bands. + * - band : specifies which band's DFT should be decoded. * * Output: - * -*fr : pointer to a buffer where the real part of DFT + * - *fr : pointer to a buffer where the real part of DFT * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part + * - *fi : pointer to a buffer where the imaginary part * of DFT coefficients are written to. * * Return value : < 0 if an error occures * 0 if succeeded. */ -int WebRtcIsac_DecodeSpecUB16( - Bitstr* streamdata, - double* fr, - double* fi); - +int WebRtcIsac_DecodeSpec(Bitstr* streamdata, WebRtc_Word16 AvgPitchGain_Q12, + enum ISACBand band, double* fr, double* fi); /****************************************************************************** - * WebRtcIsac_DecodeSpecUB12() - * Decode real and imaginary part of the DFT coefficients, given a bit-stream. - * This function is called when the codec is in 0-12 kHz bandwidth. - * The decoded DFT coefficient can be transformed to time domain by - * WebRtcIsac_Time2Spec(). + * WebRtcIsac_EncodeSpec() + * Encode real and imaginary part of the DFT coefficients into the given + * bit-stream. * * Input: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Output: - * -*fr : pointer to a buffer where the real part of DFT + * - *fr : pointer to a buffer where the real part of DFT * coefficients are written to. - * -*fi : pointer to a buffer where the imaginary part + * - *fi : pointer to a buffer where the imaginary part * of DFT coefficients are written to. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_DecodeSpecUB12( - Bitstr* streamdata, - double* fr, - double* fi); - - -/* encode complex spectrum */ -int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata, - WebRtc_Word16 AvgPitchGain_Q12); - - -/****************************************************************************** - * WebRtcIsac_EncodeSpecUB16() - * Quantize and encode real and imaginary part of the DFT coefficients. - * This function is called when the codec is in 0-16 kHz bandwidth. - * The real and imaginary part are computed by calling WebRtcIsac_Time2Spec(). - * - * - * Input: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are stored. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are stored. + * - AvgPitchGain_Q12 : average pitch-gain of the frame. This is only + * relevant for 0-4 kHz band, and the input value is + * not used in other bands. + * - band : specifies which band's DFT should be decoded. * * Output: * - streamdata : pointer to a stucture containg the encoded @@ -109,55 +72,25 @@ int WebRtcIsac_EncodeSpecLb(const WebRtc_Word16* fr, * Return value : < 0 if an error occures * 0 if succeeded. */ -int WebRtcIsac_EncodeSpecUB16( - const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata); - - -/****************************************************************************** - * WebRtcIsac_EncodeSpecUB12() - * Quantize and encode real and imaginary part of the DFT coefficients. - * This function is called when the codec is in 0-12 kHz bandwidth. - * The real and imaginary part are computed by calling WebRtcIsac_Time2Spec(). - * - * - * Input: - * -*fr : pointer to a buffer where the real part of DFT - * coefficients are stored. - * -*fi : pointer to a buffer where the imaginary part - * of DFT coefficients are stored. - * - * Output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy - * coding. - * - * Return value : < 0 if an error occures - * 0 if succeeded. - */ -int WebRtcIsac_EncodeSpecUB12( - const WebRtc_Word16* fr, - const WebRtc_Word16* fi, - Bitstr* streamdata); - +int WebRtcIsac_EncodeSpec(const WebRtc_Word16* fr, const WebRtc_Word16* fi, + WebRtc_Word16 AvgPitchGain_Q12, enum ISACBand band, + Bitstr* streamdata); /* decode & dequantize LPC Coef */ -int WebRtcIsac_DecodeLpcCoef(Bitstr *streamdata, double *LPCCoef); -int WebRtcIsac_DecodeLpcCoefUB( - Bitstr* streamdata, - double* lpcVecs, - double* percepFilterGains, - WebRtc_Word16 bandwidth); +int WebRtcIsac_DecodeLpcCoef(Bitstr* streamdata, double* LPCCoef); +int WebRtcIsac_DecodeLpcCoefUB(Bitstr* streamdata, double* lpcVecs, + double* percepFilterGains, + WebRtc_Word16 bandwidth); -int WebRtcIsac_DecodeLpc(Bitstr *streamdata, double *LPCCoef_lo, - double *LPCCoef_hi); +int WebRtcIsac_DecodeLpc(Bitstr* streamdata, double* LPCCoef_lo, + double* LPCCoef_hi); /* quantize & code LPC Coef */ -void WebRtcIsac_EncodeLpcLb(double *LPCCoef_lo, double *LPCCoef_hi, - Bitstr *streamdata, ISAC_SaveEncData_t* encData); -void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, - Bitstr *streamdata, +void WebRtcIsac_EncodeLpcLb(double* LPCCoef_lo, double* LPCCoef_hi, + Bitstr* streamdata, ISAC_SaveEncData_t* encData); + +void WebRtcIsac_EncodeLpcGainLb(double* LPCCoef_lo, double* LPCCoef_hi, + Bitstr* streamdata, ISAC_SaveEncData_t* encData); /****************************************************************************** @@ -175,8 +108,8 @@ void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, * or 0-16 kHz mode. * * Input/output: - * - streamdata : pointer to a stucture containg the encoded - * data and theparameters needed for entropy + * - streamdata : pointer to a structure containing the encoded + * data and the parameters needed for entropy * coding. * * Output: @@ -193,12 +126,10 @@ void WebRtcIsac_EncodeLpcGainLb(double *LPCCoef_lo, double *LPCCoef_hi, * Return value : 0 if encoding is successful, * <0 if failed to encode. */ -WebRtc_Word16 WebRtcIsac_EncodeLpcUB( - double* lpcCoeff, - Bitstr* streamdata, - double* interpolLPCCoeff, - WebRtc_Word16 bandwidth, - ISACUBSaveEncDataStruct* encData); +WebRtc_Word16 WebRtcIsac_EncodeLpcUB(double* lpcCoeff, Bitstr* streamdata, + double* interpolLPCCoeff, + WebRtc_Word16 bandwidth, + ISACUBSaveEncDataStruct* encData); /****************************************************************************** * WebRtcIsac_DecodeInterpolLpcUb() @@ -228,22 +159,21 @@ WebRtc_Word16 WebRtcIsac_EncodeLpcUB( * Return value : 0 if encoding is successful, * <0 if failed to encode. */ -WebRtc_Word16 WebRtcIsac_DecodeInterpolLpcUb( - Bitstr* streamdata, - double* percepFilterParam, - WebRtc_Word16 bandwidth); +WebRtc_Word16 WebRtcIsac_DecodeInterpolLpcUb(Bitstr* streamdata, + double* percepFilterParam, + WebRtc_Word16 bandwidth); -/* decode & dequantize RC */ -int WebRtcIsac_DecodeRc(Bitstr *streamdata, WebRtc_Word16 *RCQ15); +/* Decode & dequantize RC */ +int WebRtcIsac_DecodeRc(Bitstr* streamdata, WebRtc_Word16* RCQ15); -/* quantize & code RC */ -void WebRtcIsac_EncodeRc(WebRtc_Word16 *RCQ15, Bitstr *streamdata); +/* Quantize & code RC */ +void WebRtcIsac_EncodeRc(WebRtc_Word16* RCQ15, Bitstr* streamdata); -/* decode & dequantize squared Gain */ -int WebRtcIsac_DecodeGain2(Bitstr *streamdata, WebRtc_Word32 *Gain2); +/* Decode & dequantize squared Gain */ +int WebRtcIsac_DecodeGain2(Bitstr* streamdata, WebRtc_Word32* Gain2); -/* quantize & code squared Gain (input is squared gain) */ -int WebRtcIsac_EncodeGain2(WebRtc_Word32 *gain2, Bitstr *streamdata); +/* Quantize & code squared Gain (input is squared gain) */ +int WebRtcIsac_EncodeGain2(WebRtc_Word32* gain2, Bitstr* streamdata); void WebRtcIsac_EncodePitchGain(WebRtc_Word16* PitchGains_Q12, Bitstr* streamdata, @@ -252,24 +182,24 @@ void WebRtcIsac_EncodePitchGain(WebRtc_Word16* PitchGains_Q12, void WebRtcIsac_EncodePitchLag(double* PitchLags, WebRtc_Word16* PitchGain_Q12, Bitstr* streamdata, ISAC_SaveEncData_t* encData); -int WebRtcIsac_DecodePitchGain(Bitstr *streamdata, - WebRtc_Word16 *PitchGain_Q12); -int WebRtcIsac_DecodePitchLag(Bitstr *streamdata, WebRtc_Word16 *PitchGain_Q12, - double *PitchLag); +int WebRtcIsac_DecodePitchGain(Bitstr* streamdata, + WebRtc_Word16* PitchGain_Q12); +int WebRtcIsac_DecodePitchLag(Bitstr* streamdata, WebRtc_Word16* PitchGain_Q12, + double* PitchLag); -int WebRtcIsac_DecodeFrameLen(Bitstr *streamdata, WebRtc_Word16 *framelength); -int WebRtcIsac_EncodeFrameLen(WebRtc_Word16 framelength, Bitstr *streamdata); -int WebRtcIsac_DecodeSendBW(Bitstr *streamdata, WebRtc_Word16 *BWno); -void WebRtcIsac_EncodeReceiveBw(int *BWno, Bitstr *streamdata); +int WebRtcIsac_DecodeFrameLen(Bitstr* streamdata, WebRtc_Word16* framelength); +int WebRtcIsac_EncodeFrameLen(WebRtc_Word16 framelength, Bitstr* streamdata); +int WebRtcIsac_DecodeSendBW(Bitstr* streamdata, WebRtc_Word16* BWno); +void WebRtcIsac_EncodeReceiveBw(int* BWno, Bitstr* streamdata); -/* step-down */ -void WebRtcIsac_Poly2Rc(double *a, int N, double *RC); +/* Step-down */ +void WebRtcIsac_Poly2Rc(double* a, int N, double* RC); -/* step-up */ -void WebRtcIsac_Rc2Poly(double *RC, int N, double *a); +/* Step-up */ +void WebRtcIsac_Rc2Poly(double* RC, int N, double* a); -void WebRtcIsac_TranscodeLPCCoef(double *LPCCoef_lo, double *LPCCoef_hi, - int *index_g); +void WebRtcIsac_TranscodeLPCCoef(double* LPCCoef_lo, double* LPCCoef_hi, + int* index_g); /****************************************************************************** @@ -288,10 +218,8 @@ void WebRtcIsac_TranscodeLPCCoef(double *LPCCoef_lo, double *LPCCoef_hi, * - lpcGainIndex : quantization indices for lpc gains, these will * be stored to be used for FEC. */ -void WebRtcIsac_EncodeLpcGainUb( - double* lpGains, - Bitstr* streamdata, - int* lpcGainIndex); +void WebRtcIsac_EncodeLpcGainUb(double* lpGains, Bitstr* streamdata, + int* lpcGainIndex); /****************************************************************************** @@ -307,9 +235,7 @@ void WebRtcIsac_EncodeLpcGainUb( * coding. * */ -void WebRtcIsac_StoreLpcGainUb( - double* lpGains, - Bitstr* streamdata); +void WebRtcIsac_StoreLpcGainUb(double* lpGains, Bitstr* streamdata); /****************************************************************************** @@ -327,9 +253,7 @@ void WebRtcIsac_StoreLpcGainUb( * Return value : 0 if succeeded. * <0 if failed. */ -WebRtc_Word16 WebRtcIsac_DecodeLpcGainUb( - double* lpGains, - Bitstr* streamdata); +WebRtc_Word16 WebRtcIsac_DecodeLpcGainUb(double* lpGains, Bitstr* streamdata); /****************************************************************************** @@ -348,9 +272,8 @@ WebRtc_Word16 WebRtcIsac_DecodeLpcGainUb( * Return value : 0 if succeeded. * <0 if failed. */ -WebRtc_Word16 WebRtcIsac_EncodeBandwidth( - enum ISACBandwidth bandwidth, - Bitstr* streamData); +WebRtc_Word16 WebRtcIsac_EncodeBandwidth(enum ISACBandwidth bandwidth, + Bitstr* streamData); /****************************************************************************** @@ -370,9 +293,8 @@ WebRtc_Word16 WebRtcIsac_EncodeBandwidth( * Return value : 0 if succeeded. * <0 if failed. */ -WebRtc_Word16 WebRtcIsac_DecodeBandwidth( - Bitstr* streamData, - enum ISACBandwidth* bandwidth); +WebRtc_Word16 WebRtcIsac_DecodeBandwidth(Bitstr* streamData, + enum ISACBandwidth* bandwidth); /****************************************************************************** @@ -392,9 +314,8 @@ WebRtc_Word16 WebRtcIsac_DecodeBandwidth( * Return value : 0 if succeeded. * <0 if failed. */ -WebRtc_Word16 WebRtcIsac_EncodeJitterInfo( - WebRtc_Word32 jitterIndex, - Bitstr* streamData); +WebRtc_Word16 WebRtcIsac_EncodeJitterInfo(WebRtc_Word32 jitterIndex, + Bitstr* streamData); /****************************************************************************** @@ -414,8 +335,7 @@ WebRtc_Word16 WebRtcIsac_EncodeJitterInfo( * Return value : 0 if succeeded. * <0 if failed. */ -WebRtc_Word16 WebRtcIsac_DecodeJitterInfo( - Bitstr* streamData, - WebRtc_Word32* jitterInfo); +WebRtc_Word16 WebRtcIsac_DecodeJitterInfo(Bitstr* streamData, + WebRtc_Word32* jitterInfo); #endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_ENTROPY_CODING_H_ */ diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/isac.c b/src/modules/audio_coding/codecs/iSAC/main/source/isac.c index 67db1e4c9b..7c90334670 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/isac.c +++ b/src/modules/audio_coding/codecs/iSAC/main/source/isac.c @@ -38,7 +38,7 @@ /**************************************************************************** - * UpdatePayloadSizeLimit() + * UpdatePayloadSizeLimit(...) * * Call this function to update the limit on the payload size. The limit on * payload size might change i) if a user ''directly changes the limit by @@ -46,73 +46,58 @@ * when bandwidth is changing. The latter might be the result of bandwidth * adaptation, or direct change of the bottleneck in instantaneous mode. * - * This function takes the current overall limit on payload, and translate it - * to the limits on lower and upper-band. If the codec is in wideband mode + * This function takes the current overall limit on payload, and translates it + * to the limits on lower and upper-band. If the codec is in wideband mode, * then the overall limit and the limit on the lower-band is the same. * Otherwise, a fraction of the limit should be allocated to lower-band * leaving some room for the upper-band bit-stream. That is why an update * of limit is required every time that the bandwidth is changing. * */ -static void UpdatePayloadSizeLimit( - ISACMainStruct *instISAC) -{ - WebRtc_Word16 lim30MsPayloadBytes; - WebRtc_Word16 lim60MsPayloadBytes; +static void UpdatePayloadSizeLimit(ISACMainStruct* instISAC) { + WebRtc_Word16 lim30MsPayloadBytes = WEBRTC_SPL_MIN( + (instISAC->maxPayloadSizeBytes), + (instISAC->maxRateBytesPer30Ms)); + WebRtc_Word16 lim60MsPayloadBytes = WEBRTC_SPL_MIN( + (instISAC->maxPayloadSizeBytes), + (instISAC->maxRateBytesPer30Ms << 1)); - lim30MsPayloadBytes = WEBRTC_SPL_MIN( - (instISAC->maxPayloadSizeBytes), - (instISAC->maxRateBytesPer30Ms)); + /* The only time that iSAC will have 60 ms + * frame-size is when operating in wideband, so + * there is no upper-band bit-stream. */ - lim60MsPayloadBytes = WEBRTC_SPL_MIN( - (instISAC->maxPayloadSizeBytes), - (instISAC->maxRateBytesPer30Ms << 1)); - - // The only time that iSAC will have 60 ms - // frame-size is when operating in wideband so - // there is no upper-band bit-stream - - if(instISAC->bandwidthKHz == isac8kHz) - { - // at 8 kHz there is no upper-band bit-stream - // therefore the lower-band limit is as the overall - // limit. - instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 = - lim60MsPayloadBytes; + if (instISAC->bandwidthKHz == isac8kHz) { + /* At 8 kHz there is no upper-band bit-stream, + * therefore, the lower-band limit is the overall limit. */ + instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 = + lim60MsPayloadBytes; + instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = + lim30MsPayloadBytes; + } else { + /* When in super-wideband, we only have 30 ms frames. + * Do a rate allocation for the given limit. */ + if (lim30MsPayloadBytes > 250) { + /* 4/5 to lower-band the rest for upper-band. */ instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - lim30MsPayloadBytes; - } - else - { - // when in super-wideband, we only have 30 ms frames - // Do a rate allocation for the given limit. - if(lim30MsPayloadBytes > 250) - { - // 4/5 to lower-band the rest for upper-band - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - (lim30MsPayloadBytes << 2) / 5; - } - else if(lim30MsPayloadBytes > 200) - { - // for the interval of 200 to 250 the share of - // upper-band linearly grows from 20 to 50; - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - (lim30MsPayloadBytes << 1) / 5 + 100; - } - else - { - // allocate only 20 for upper-band - instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = - lim30MsPayloadBytes - 20; - } - instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes = - lim30MsPayloadBytes; + (lim30MsPayloadBytes << 2) / 5; + } else if (lim30MsPayloadBytes > 200) { + /* For the interval of 200 to 250 the share of + * upper-band linearly grows from 20 to 50. */ + instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = + (lim30MsPayloadBytes << 1) / 5 + 100; + } else { + /* Allocate only 20 for upper-band. */ + instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = + lim30MsPayloadBytes - 20; } + instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes = + lim30MsPayloadBytes; + } } /**************************************************************************** - * UpdateBottleneck() + * UpdateBottleneck(...) * * This function updates the bottleneck only if the codec is operating in * channel-adaptive mode. Furthermore, as the update of bottleneck might @@ -120,87 +105,76 @@ static void UpdatePayloadSizeLimit( * updated just right before the first 10ms of a frame is pushed into encoder. * */ -static void UpdateBottleneck( - ISACMainStruct *instISAC) -{ - // read the bottleneck from bandwidth estimator for the - // first 10 ms audio. This way, if there is a change - // in bandwidth upper and lower-band will be in sync. - if((instISAC->codingMode == 0) && - (instISAC->instLB.ISACencLB_obj.buffer_index == 0) && - (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) - { - WebRtc_Word32 bottleneck; - WebRtcIsac_GetUplinkBandwidth(&(instISAC->bwestimator_obj), - &bottleneck); +static void UpdateBottleneck(ISACMainStruct* instISAC) { + /* Read the bottleneck from bandwidth estimator for the + * first 10 ms audio. This way, if there is a change + * in bandwidth, upper and lower-band will be in sync. */ + if ((instISAC->codingMode == 0) && + (instISAC->instLB.ISACencLB_obj.buffer_index == 0) && + (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) { + WebRtc_Word32 bottleneck; + WebRtcIsac_GetUplinkBandwidth(&(instISAC->bwestimator_obj), + &bottleneck); - // Adding hysteresis when increasing signal bandwidth - if((instISAC->bandwidthKHz == isac8kHz) - && (bottleneck > 37000) - && (bottleneck < 41000)) - { - bottleneck = 37000; - } - - // switching from 12 kHz to 16 kHz is not allowed at this revision - // If we let this happen, we have to take care of buffer_index and - // the last LPC vector. - if((instISAC->bandwidthKHz != isac16kHz) && - (bottleneck > 46000)) - { - bottleneck = 46000; - } - - // we might need a rate allocation. - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - // wideband is the only choise we have here. - instISAC->instLB.ISACencLB_obj.bottleneck = - (bottleneck > 32000)? 32000:bottleneck; - instISAC->bandwidthKHz = isac8kHz; - } - else - { - // do the rate-allosation and get the new bandwidth. - enum ISACBandwidth bandwidth; - WebRtcIsac_RateAllocation(bottleneck, - &(instISAC->instLB.ISACencLB_obj.bottleneck), - &(instISAC->instUB.ISACencUB_obj.bottleneck), - &bandwidth); - if(bandwidth != isac8kHz) - { - instISAC->instLB.ISACencLB_obj.new_framelength = 480; - } - if(bandwidth != instISAC->bandwidthKHz) - { - // bandwidth is changing. - instISAC->bandwidthKHz = bandwidth; - UpdatePayloadSizeLimit(instISAC); - if(bandwidth == isac12kHz) - { - instISAC->instLB.ISACencLB_obj.buffer_index = 0; - } - // currently we don't let the bandwidth to switch to 16 kHz - // if in adaptive mode. If we let this happen, we have to take - // car of buffer_index and the last LPC vector. - } - } + /* Adding hysteresis when increasing signal bandwidth. */ + if ((instISAC->bandwidthKHz == isac8kHz) + && (bottleneck > 37000) + && (bottleneck < 41000)) { + bottleneck = 37000; } + + /* Switching from 12 kHz to 16 kHz is not allowed at this revision. + * If we let this happen, we have to take care of buffer_index and + * the last LPC vector. */ + if ((instISAC->bandwidthKHz != isac16kHz) && + (bottleneck > 46000)) { + bottleneck = 46000; + } + + /* We might need a rate allocation. */ + if (instISAC->encoderSamplingRateKHz == kIsacWideband) { + /* Wideband is the only choice we have here. */ + instISAC->instLB.ISACencLB_obj.bottleneck = + (bottleneck > 32000) ? 32000 : bottleneck; + instISAC->bandwidthKHz = isac8kHz; + } else { + /* Do the rate-allocation and get the new bandwidth. */ + enum ISACBandwidth bandwidth; + WebRtcIsac_RateAllocation(bottleneck, + &(instISAC->instLB.ISACencLB_obj.bottleneck), + &(instISAC->instUB.ISACencUB_obj.bottleneck), + &bandwidth); + if (bandwidth != isac8kHz) { + instISAC->instLB.ISACencLB_obj.new_framelength = 480; + } + if (bandwidth != instISAC->bandwidthKHz) { + /* Bandwidth is changing. */ + instISAC->bandwidthKHz = bandwidth; + UpdatePayloadSizeLimit(instISAC); + if (bandwidth == isac12kHz) { + instISAC->instLB.ISACencLB_obj.buffer_index = 0; + } + /* Currently we don't let the bandwidth to switch to 16 kHz + * if in adaptive mode. If we let this happen, we have to take + * care of buffer_index and the last LPC vector. */ + } + } + } } /**************************************************************************** - * GetSendBandwidthInfo() + * GetSendBandwidthInfo(...) * * This is called to get the bandwidth info. This info is the bandwidth and - * and the jitter of 'there-to-here' channel, estimated 'here.' These info - * is signaled in an in-band fashion to the otherside. + * the jitter of 'there-to-here' channel, estimated 'here.' These info + * is signaled in an in-band fashion to the other side. * - * The call to the bandwidth estimator trigers a recursive averaging which - * has to be synchronized between encoder & decoder, therefore. The call to + * The call to the bandwidth estimator triggers a recursive averaging which + * has to be synchronized between encoder & decoder, therefore, the call to * BWE should be once per packet. As the BWE info is inserted into bit-stream - * we need a valid info right before the encodeLB function is going to - * generating a bit-stream. That is when lower-band buffer has already 20ms + * We need a valid info right before the encodeLB function is going to + * generate a bit-stream. That is when lower-band buffer has already 20ms * of audio, and the 3rd block of 10ms is going to be injected into encoder. * * Inputs: @@ -215,19 +189,17 @@ static void UpdateBottleneck( * bit-stream. * */ -static void GetSendBandwidthInfo( - ISACMainStruct* instISAC, - WebRtc_Word16* bandwidthIndex, - WebRtc_Word16* jitterInfo) -{ - if((instISAC->instLB.ISACencLB_obj.buffer_index == +static void GetSendBandwidthInfo(ISACMainStruct* instISAC, + WebRtc_Word16* bandwidthIndex, + WebRtc_Word16* jitterInfo) { + if ((instISAC->instLB.ISACencLB_obj.buffer_index == (FRAMESAMPLES_10ms << 1)) && - (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) - { - /* bandwidth estimation and coding */ - WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), - bandwidthIndex, jitterInfo, instISAC->decoderSamplingRateKHz); - } + (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) { + /* Bandwidth estimation and coding. */ + WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), + bandwidthIndex, jitterInfo, + instISAC->decoderSamplingRateKHz); + } } @@ -244,9 +216,7 @@ static void GetSendBandwidthInfo( * Return value : 0 - Ok * -1 - Error */ -WebRtc_Word16 WebRtcIsac_AssignSize( - int *sizeInBytes) -{ +WebRtc_Word16 WebRtcIsac_AssignSize(int* sizeInBytes) { *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(WebRtc_Word16); return 0; } @@ -255,39 +225,34 @@ WebRtc_Word16 WebRtcIsac_AssignSize( /**************************************************************************** * WebRtcIsac_Assign(...) * - * This function assignes the memory already created to the ISAC instance. + * This function assigns the memory already created to the ISAC instance. * * Input: * - ISAC_main_inst : address of the pointer to the coder instance. - * - instISAC_Addr : the already allocaded memeory, where we put the - * iSAC struct + * - instISAC_Addr : the already allocated memory, where we put the + * iSAC structure. * * Return value : 0 - Ok * -1 - Error */ -WebRtc_Word16 WebRtcIsac_Assign( - ISACStruct** ISAC_main_inst, - void* instISAC_Addr) -{ - if(instISAC_Addr != NULL) - { - ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr; - instISAC->errorCode = 0; - instISAC->initFlag = 0; +WebRtc_Word16 WebRtcIsac_Assign(ISACStruct** ISAC_main_inst, + void* instISAC_Addr) { + if (instISAC_Addr != NULL) { + ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr; + instISAC->errorCode = 0; + instISAC->initFlag = 0; - // Assign the address - *ISAC_main_inst = (ISACStruct*)instISAC_Addr; + /* Assign the address. */ + *ISAC_main_inst = (ISACStruct*)instISAC_Addr; - // Default is wideband. - instISAC->encoderSamplingRateKHz = kIsacWideband; - instISAC->decoderSamplingRateKHz = kIsacWideband; - instISAC->bandwidthKHz = isac8kHz; - return 0; - } - else - { - return -1; - } + /* Default is wideband. */ + instISAC->encoderSamplingRateKHz = kIsacWideband; + instISAC->decoderSamplingRateKHz = kIsacWideband; + instISAC->bandwidthKHz = isac8kHz; + return 0; + } else { + return -1; + } } @@ -303,27 +268,22 @@ WebRtc_Word16 WebRtcIsac_Assign( * Return value : 0 - Ok * -1 - Error */ -WebRtc_Word16 WebRtcIsac_Create( - ISACStruct** ISAC_main_inst) -{ +WebRtc_Word16 WebRtcIsac_Create(ISACStruct** ISAC_main_inst) { ISACMainStruct* instISAC; instISAC = (ISACMainStruct*)WEBRTC_SPL_VNEW(ISACMainStruct, 1); *ISAC_main_inst = (ISACStruct*)instISAC; - if(*ISAC_main_inst != NULL) - { - instISAC->errorCode = 0; - instISAC->initFlag = 0; - // Default is wideband - instISAC->bandwidthKHz = isac8kHz; - instISAC->encoderSamplingRateKHz = kIsacWideband; - instISAC->decoderSamplingRateKHz = kIsacWideband; - return 0; - } - else - { - return -1; - } + if (*ISAC_main_inst != NULL) { + instISAC->errorCode = 0; + instISAC->initFlag = 0; + /* Default is wideband. */ + instISAC->bandwidthKHz = isac8kHz; + instISAC->encoderSamplingRateKHz = kIsacWideband; + instISAC->decoderSamplingRateKHz = kIsacWideband; + return 0; + } else { + return -1; + } } @@ -338,12 +298,8 @@ WebRtc_Word16 WebRtcIsac_Create( * Return value : 0 - Ok * -1 - Error */ -WebRtc_Word16 WebRtcIsac_Free( - ISACStruct* ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; +WebRtc_Word16 WebRtcIsac_Free(ISACStruct* ISAC_main_inst) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; WEBRTC_SPL_FREE(instISAC); return 0; } @@ -371,86 +327,73 @@ WebRtc_Word16 WebRtcIsac_Free( * Return value : 0 - Ok * -1 - Error */ -static WebRtc_Word16 EncoderInitLb( - ISACLBStruct* instLB, - WebRtc_Word16 codingMode, - enum IsacSamplingRate sampRate) -{ +static WebRtc_Word16 EncoderInitLb(ISACLBStruct* instLB, + WebRtc_Word16 codingMode, + enum IsacSamplingRate sampRate) { WebRtc_Word16 statusInit = 0; int k; /* Init stream vector to zero */ - for(k=0; k < STREAM_SIZE_MAX_60; k++) - { - instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0; - } + for (k = 0; k < STREAM_SIZE_MAX_60; k++) { + instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0; + } - if((codingMode == 1) || (sampRate == kIsacSuperWideband)) - { - // 30 ms frame-size if either in super-wideband or - // instanteneous mode (I-mode) - instLB->ISACencLB_obj.new_framelength = 480; - } - else - { - instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES; - } + if ((codingMode == 1) || (sampRate == kIsacSuperWideband)) { + /* 30 ms frame-size if either in super-wideband or + * instantaneous mode (I-mode). */ + instLB->ISACencLB_obj.new_framelength = 480; + } else { + instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES; + } WebRtcIsac_InitMasking(&instLB->ISACencLB_obj.maskfiltstr_obj); WebRtcIsac_InitPreFilterbank(&instLB->ISACencLB_obj.prefiltbankstr_obj); WebRtcIsac_InitPitchFilter(&instLB->ISACencLB_obj.pitchfiltstr_obj); WebRtcIsac_InitPitchAnalysis( - &instLB->ISACencLB_obj.pitchanalysisstr_obj); + &instLB->ISACencLB_obj.pitchanalysisstr_obj); - - instLB->ISACencLB_obj.buffer_index = 0; - instLB->ISACencLB_obj.frame_nb = 0; - /* default for I-mode */ - instLB->ISACencLB_obj.bottleneck = 32000; + instLB->ISACencLB_obj.buffer_index = 0; + instLB->ISACencLB_obj.frame_nb = 0; + /* Default for I-mode. */ + instLB->ISACencLB_obj.bottleneck = 32000; instLB->ISACencLB_obj.current_framesamples = 0; - instLB->ISACencLB_obj.s2nr = 0; - instLB->ISACencLB_obj.payloadLimitBytes30 = STREAM_SIZE_MAX_30; - instLB->ISACencLB_obj.payloadLimitBytes60 = STREAM_SIZE_MAX_60; - instLB->ISACencLB_obj.maxPayloadBytes = STREAM_SIZE_MAX_60; - instLB->ISACencLB_obj.maxRateInBytes = STREAM_SIZE_MAX_30; - instLB->ISACencLB_obj.enforceFrameSize = 0; - /* invalid value prevents getRedPayload to - run before encoder is called */ + instLB->ISACencLB_obj.s2nr = 0; + instLB->ISACencLB_obj.payloadLimitBytes30 = STREAM_SIZE_MAX_30; + instLB->ISACencLB_obj.payloadLimitBytes60 = STREAM_SIZE_MAX_60; + instLB->ISACencLB_obj.maxPayloadBytes = STREAM_SIZE_MAX_60; + instLB->ISACencLB_obj.maxRateInBytes = STREAM_SIZE_MAX_30; + instLB->ISACencLB_obj.enforceFrameSize = 0; + /* Invalid value prevents getRedPayload to + run before encoder is called. */ instLB->ISACencLB_obj.lastBWIdx = -1; return statusInit; } -static WebRtc_Word16 EncoderInitUb( - ISACUBStruct* instUB, - WebRtc_Word16 bandwidth) -{ +static WebRtc_Word16 EncoderInitUb(ISACUBStruct* instUB, + WebRtc_Word16 bandwidth) { WebRtc_Word16 statusInit = 0; int k; - /* Init stream vector to zero */ - for(k = 0; k < STREAM_SIZE_MAX_60; k++) - { - instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0; - } + /* Init stream vector to zero. */ + for (k = 0; k < STREAM_SIZE_MAX_60; k++) { + instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0; + } WebRtcIsac_InitMasking(&instUB->ISACencUB_obj.maskfiltstr_obj); WebRtcIsac_InitPreFilterbank(&instUB->ISACencUB_obj.prefiltbankstr_obj); - if(bandwidth == isac16kHz) - { - instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES; - } - else - { - instUB->ISACencUB_obj.buffer_index = 0; - } - /* default for I-mode */ - instUB->ISACencUB_obj.bottleneck = 32000; - // These store the limits for the wideband + super-wideband bit-stream. - instUB->ISACencUB_obj.maxPayloadSizeBytes = STREAM_SIZE_MAX_30 << 1; - // This has to be updated after each lower-band encoding to guarantee - // a correct payload-limitation. - instUB->ISACencUB_obj.numBytesUsed = 0; + if (bandwidth == isac16kHz) { + instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES; + } else { + instUB->ISACencUB_obj.buffer_index = 0; + } + /* Default for I-mode. */ + instUB->ISACencUB_obj.bottleneck = 32000; + /* These store the limits for the wideband + super-wideband bit-stream. */ + instUB->ISACencUB_obj.maxPayloadSizeBytes = STREAM_SIZE_MAX_30 << 1; + /* This has to be updated after each lower-band encoding to guarantee + * a correct payload-limitation. */ + instUB->ISACencUB_obj.numBytesUsed = 0; memset(instUB->ISACencUB_obj.data_buffer_float, 0, (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES) * sizeof(float)); @@ -461,37 +404,29 @@ static WebRtc_Word16 EncoderInitUb( } -WebRtc_Word16 WebRtcIsac_EncoderInit( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 codingMode) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_EncoderInit(ISACStruct* ISAC_main_inst, + WebRtc_Word16 codingMode) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; WebRtc_Word16 status; - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if((codingMode != 0) && (codingMode != 1)) - { - instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE; - return -1; - } - // default bottleneck + if ((codingMode != 0) && (codingMode != 1)) { + instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE; + return -1; + } + /* Default bottleneck. */ instISAC->bottleneck = MAX_ISAC_BW; - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - instISAC->bandwidthKHz = isac8kHz; - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; - } - else - { - instISAC->bandwidthKHz = isac16kHz; - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; - } + if (instISAC->encoderSamplingRateKHz == kIsacWideband) { + instISAC->bandwidthKHz = isac8kHz; + instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; + instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; + } else { + instISAC->bandwidthKHz = isac16kHz; + instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; + instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; + } - // Channel-adaptive = 0; Instantaneous (Channel-independent) = 1; + /* Channel-adaptive = 0; Instantaneous (Channel-independent) = 1. */ instISAC->codingMode = codingMode; WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, @@ -499,34 +434,31 @@ WebRtc_Word16 WebRtcIsac_EncoderInit( instISAC->decoderSamplingRateKHz); WebRtcIsac_InitRateModel(&instISAC->rate_data_obj); - /* default for I-mode */ + /* Default for I-mode. */ instISAC->MaxDelay = 10.0; status = EncoderInitLb(&instISAC->instLB, codingMode, - instISAC->encoderSamplingRateKHz); - if(status < 0) - { + instISAC->encoderSamplingRateKHz); + if (status < 0) { + instISAC->errorCode = -status; + return -1; + } + + if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { + /* Initialize encoder filter-bank. */ + memset(instISAC->analysisFBState1, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); + memset(instISAC->analysisFBState2, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); + + status = EncoderInitUb(&(instISAC->instUB), + instISAC->bandwidthKHz); + if (status < 0) { instISAC->errorCode = -status; return -1; } - - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - // Initialize encoder filter-bank. - memset(instISAC->analysisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->analysisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - status = EncoderInitUb(&(instISAC->instUB), - instISAC->bandwidthKHz); - if(status < 0) - { - instISAC->errorCode = -status; - return -1; - } - } - // Initializtion is successful, set the flag + } + /* Initialization is successful, set the flag. */ instISAC->initFlag |= BIT_MASK_ENC_INIT; return 0; } @@ -554,294 +486,234 @@ WebRtc_Word16 WebRtcIsac_EncoderInit( * samples. * : -1 - Error */ -WebRtc_Word16 WebRtcIsac_Encode( - ISACStruct* ISAC_main_inst, - const WebRtc_Word16* speechIn, - WebRtc_Word16* encoded) -{ - ISACMainStruct* instISAC; - ISACLBStruct* instLB; - ISACUBStruct* instUB; - - float inFrame[FRAMESAMPLES_10ms]; - WebRtc_Word16 speechInLB[FRAMESAMPLES_10ms]; - WebRtc_Word16 speechInUB[FRAMESAMPLES_10ms]; - WebRtc_Word16 streamLenLB = 0; - WebRtc_Word16 streamLenUB = 0; - WebRtc_Word16 streamLen = 0; - WebRtc_Word16 k = 0; +WebRtc_Word16 WebRtcIsac_Encode(ISACStruct* ISAC_main_inst, + const WebRtc_Word16* speechIn, + WebRtc_Word16* encoded) { + float inFrame[FRAMESAMPLES_10ms]; + WebRtc_Word16 speechInLB[FRAMESAMPLES_10ms]; + WebRtc_Word16 speechInUB[FRAMESAMPLES_10ms]; + WebRtc_Word16 streamLenLB = 0; + WebRtc_Word16 streamLenUB = 0; + WebRtc_Word16 streamLen = 0; + WebRtc_Word16 k = 0; WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; - int garbageLen = 0; - WebRtc_Word32 bottleneck = 0; - WebRtc_Word16 bottleneckIdx = 0; - WebRtc_Word16 jitterInfo = 0; + int garbageLen = 0; + WebRtc_Word32 bottleneck = 0; + WebRtc_Word16 bottleneckIdx = 0; + WebRtc_Word16 jitterInfo = 0; - instISAC = (ISACMainStruct*)ISAC_main_inst; - instLB = &(instISAC->instLB); - instUB = &(instISAC->instUB); + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; + ISACLBStruct* instLB = &(instISAC->instLB); + ISACUBStruct* instUB = &(instISAC->instUB); - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; + /* Check if encoder initiated. */ + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } + + if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { + WebRtcSpl_AnalysisQMF(speechIn, speechInLB, speechInUB, + instISAC->analysisFBState1, + instISAC->analysisFBState2); + + /* Convert from fixed to floating point. */ + for (k = 0; k < FRAMESAMPLES_10ms; k++) { + inFrame[k] = (float)speechInLB[k]; } - - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - WebRtcSpl_AnalysisQMF(speechIn, speechInLB, speechInUB, - instISAC->analysisFBState1, instISAC->analysisFBState2); - - /* convert from fixed to floating point */ - for(k = 0; k < FRAMESAMPLES_10ms; k++) - { - inFrame[k] = (float)speechInLB[k]; - } - } - else - { - for(k = 0; k < FRAMESAMPLES_10ms; k++) - { - inFrame[k] = (float) speechIn[k]; - } + } else { + for (k = 0; k < FRAMESAMPLES_10ms; k++) { + inFrame[k] = (float) speechIn[k]; } + } - /* add some noise to avoid denormal numbers */ + /* Add some noise to avoid denormal numbers. */ inFrame[0] += (float)1.23455334e-3; inFrame[1] -= (float)2.04324239e-3; inFrame[2] += (float)1.90854954e-3; inFrame[9] += (float)1.84854878e-3; - - // This function will update the bottleneck if required + /* This function will update the bottleneck if required. */ UpdateBottleneck(instISAC); - // Get the bandwith information which has to be sent to the other side + /* Get the bandwith information which has to be sent to the other side. */ GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo); - // - // ENCODE LOWER-BAND - // + /* Encode lower-band. */ streamLenLB = WebRtcIsac_EncodeLb(inFrame, &instLB->ISACencLB_obj, instISAC->codingMode, bottleneckIdx); + if (streamLenLB < 0) { + return -1; + } - if(streamLenLB < 0) - { + if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { + instUB = &(instISAC->instUB); + + /* Convert to float. */ + for (k = 0; k < FRAMESAMPLES_10ms; k++) { + inFrame[k] = (float) speechInUB[k]; + } + + /* Add some noise to avoid denormal numbers. */ + inFrame[0] += (float)1.23455334e-3; + inFrame[1] -= (float)2.04324239e-3; + inFrame[2] += (float)1.90854954e-3; + inFrame[9] += (float)1.84854878e-3; + + /* Tell to upper-band the number of bytes used so far. + * This is for payload limitation. */ + instUB->ISACencUB_obj.numBytesUsed = streamLenLB + 1 + + LEN_CHECK_SUM_WORD8; + /* Encode upper-band. */ + switch (instISAC->bandwidthKHz) { + case isac12kHz: { + streamLenUB = WebRtcIsac_EncodeUb12(inFrame, &instUB->ISACencUB_obj, + jitterInfo); + break; + } + case isac16kHz: { + streamLenUB = WebRtcIsac_EncodeUb16(inFrame, &instUB->ISACencUB_obj, + jitterInfo); + break; + } + case isac8kHz: { + streamLenUB = 0; + break; + } + } + + if ((streamLenUB < 0) && (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) { + /* An error has happened but this is not the error due to a + * bit-stream larger than the limit. */ return -1; } - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - instUB = &(instISAC->instUB); - - // convert to float - for(k = 0; k < FRAMESAMPLES_10ms; k++) - { - inFrame[k] = (float) speechInUB[k]; - } - - /* add some noise to avoid denormal numbers */ - inFrame[0] += (float)1.23455334e-3; - inFrame[1] -= (float)2.04324239e-3; - inFrame[2] += (float)1.90854954e-3; - inFrame[9] += (float)1.84854878e-3; - - // Tell to upper-band the number of bytes used so far. - // This is for payload limitation. - instUB->ISACencUB_obj.numBytesUsed = streamLenLB + 1 + - LEN_CHECK_SUM_WORD8; - - // - // ENCODE UPPER-BAND - // - switch(instISAC->bandwidthKHz) - { - case isac12kHz: - { - streamLenUB = WebRtcIsac_EncodeUb12(inFrame, - &instUB->ISACencUB_obj, - jitterInfo); - break; - } - case isac16kHz: - { - streamLenUB = WebRtcIsac_EncodeUb16(inFrame, - &instUB->ISACencUB_obj, - jitterInfo); - break; - } - case isac8kHz: - { - streamLenUB = 0; - break; - } - } - - if((streamLenUB < 0) && - (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) - { - // an error has happened but this is not the error due to a - // bit-stream larger than the limit - return -1; - } - - if(streamLenLB == 0) - { - return 0; - } - - // One bite is allocated for the length. According to older decoders - // so the length bit-stream plus one byte for size and - // LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal - // to 255. - if((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) || - (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) - { - // we have got a too long bit-stream we skip the upper-band - // bit-stream for this frame. - streamLenUB = 0; - } - - memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, - streamLenLB); - streamLen = streamLenLB; - if(streamLenUB > 0) - { - ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)(streamLenUB + 1 + - LEN_CHECK_SUM_WORD8); - memcpy(&ptrEncodedUW8[streamLenLB + 1], - instUB->ISACencUB_obj.bitstr_obj.stream, streamLenUB); - streamLen += ptrEncodedUW8[streamLenLB]; - } - else - { - ptrEncodedUW8[streamLenLB] = 0; - } + if (streamLenLB == 0) { + return 0; } - else - { - if(streamLenLB == 0) - { - return 0; - } - memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, - streamLenLB); + + /* One byte is allocated for the length. According to older decoders + so the length bit-stream plus one byte for size and + LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal + to 255. */ + if ((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) || + (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) { + /* We have got a too long bit-stream we skip the upper-band + * bit-stream for this frame. */ streamLenUB = 0; - streamLen = streamLenLB; } - // Add Garbage if required. + memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB); + streamLen = streamLenLB; + if (streamLenUB > 0) { + ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)(streamLenUB + 1 + + LEN_CHECK_SUM_WORD8); + memcpy(&ptrEncodedUW8[streamLenLB + 1], + instUB->ISACencUB_obj.bitstr_obj.stream, streamLenUB); + streamLen += ptrEncodedUW8[streamLenLB]; + } else { + ptrEncodedUW8[streamLenLB] = 0; + } + } else { + if (streamLenLB == 0) { + return 0; + } + memcpy(ptrEncodedUW8, instLB->ISACencLB_obj.bitstr_obj.stream, + streamLenLB); + streamLenUB = 0; + streamLen = streamLenLB; + } + + /* Add Garbage if required. */ WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj, &bottleneck); - if(instISAC->codingMode == 0) - { - int minBytes; - int limit; - WebRtc_UWord8* ptrGarbage; + if (instISAC->codingMode == 0) { + int minBytes; + int limit; + WebRtc_UWord8* ptrGarbage; - instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay( - &instISAC->bwestimator_obj); + instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay( + &instISAC->bwestimator_obj); - /* update rate model and get minimum number of bytes in this packet */ - minBytes = WebRtcIsac_GetMinBytes(&(instISAC->rate_data_obj), - streamLen, instISAC->instLB.ISACencLB_obj.current_framesamples, - bottleneck, instISAC->MaxDelay, instISAC->bandwidthKHz); + /* Update rate model and get minimum number of bytes in this packet. */ + minBytes = WebRtcIsac_GetMinBytes( + &(instISAC->rate_data_obj), streamLen, + instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck, + instISAC->MaxDelay, instISAC->bandwidthKHz); - /* Make sure MinBytes does not exceed packet size limit */ - if(instISAC->bandwidthKHz == isac8kHz) - { - if(instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES) - { - limit = instLB->ISACencLB_obj.payloadLimitBytes30; - } - else - { - limit = instLB->ISACencLB_obj.payloadLimitBytes60; - } - } - else - { - limit = instUB->ISACencUB_obj.maxPayloadSizeBytes; - } - minBytes = (minBytes > limit)? limit:minBytes; - - /* Make sure we don't allow more than 255 bytes of garbage data. - We store the length of the garbage data in 8 bits in the bitstream, - 255 is the max garbage length we can signal using 8 bits. */ - if((instISAC->bandwidthKHz == isac8kHz) || - (streamLenUB == 0)) - { - ptrGarbage = &ptrEncodedUW8[streamLenLB]; - limit = streamLen + 255; - } - else - { - ptrGarbage = &ptrEncodedUW8[streamLenLB + 1 + streamLenUB]; - limit = streamLen + (255 - ptrEncodedUW8[streamLenLB]); - } - minBytes = (minBytes > limit)? limit:minBytes; - - garbageLen = (minBytes > streamLen)? (minBytes - streamLen):0; - - /* Save data for creation of multiple bitstreams */ - //ISACencLB_obj->SaveEnc_obj.minBytes = MinBytes; - - /* if bitstream is too short, add garbage at the end */ - if(garbageLen > 0) - { - for(k = 0; k < garbageLen; k++) - { - ptrGarbage[k] = (WebRtc_UWord8)(rand() & 0xFF); - } - - // for a correct length of the upper-band bit-stream together - // with the garbage. Garbage is embeded in upper-band bit-stream. - // That is the only way to preserve backward compatibility. - if((instISAC->bandwidthKHz == isac8kHz) || - (streamLenUB == 0)) - { - ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)garbageLen; - } - else - { - ptrEncodedUW8[streamLenLB] += (WebRtc_UWord8)garbageLen; - // write the length of the garbage at the end of the upper-band - // bit-stream, if exists. This helps for sanity check. - ptrEncodedUW8[streamLenLB + 1 + streamLenUB] = (WebRtc_UWord8)garbageLen; - - } - - streamLen += garbageLen; - } + /* Make sure MinBytes does not exceed packet size limit. */ + if (instISAC->bandwidthKHz == isac8kHz) { + if (instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES) { + limit = instLB->ISACencLB_obj.payloadLimitBytes30; + } else { + limit = instLB->ISACencLB_obj.payloadLimitBytes60; + } + } else { + limit = instUB->ISACencUB_obj.maxPayloadSizeBytes; } - else - { - /* update rate model */ - WebRtcIsac_UpdateRateModel(&instISAC->rate_data_obj, streamLen, - instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck); - garbageLen = 0; + minBytes = (minBytes > limit) ? limit : minBytes; + + /* Make sure we don't allow more than 255 bytes of garbage data. + * We store the length of the garbage data in 8 bits in the bitstream, + * 255 is the max garbage length we can signal using 8 bits. */ + if ((instISAC->bandwidthKHz == isac8kHz) || + (streamLenUB == 0)) { + ptrGarbage = &ptrEncodedUW8[streamLenLB]; + limit = streamLen + 255; + } else { + ptrGarbage = &ptrEncodedUW8[streamLenLB + 1 + streamLenUB]; + limit = streamLen + (255 - ptrEncodedUW8[streamLenLB]); } + minBytes = (minBytes > limit) ? limit : minBytes; - // Generate CRC if required. - if((instISAC->bandwidthKHz != isac8kHz) && - (streamLenUB > 0)) - { - WebRtc_UWord32 crc; + garbageLen = (minBytes > streamLen) ? (minBytes - streamLen) : 0; - WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), - streamLenUB + garbageLen, &crc); + /* Save data for creation of multiple bit-streams. */ + /* If bit-stream too short then add garbage at the end. */ + if (garbageLen > 0) { + for (k = 0; k < garbageLen; k++) { + ptrGarbage[k] = (WebRtc_UWord8)(rand() & 0xFF); + } + /* For a correct length of the upper-band bit-stream together + * with the garbage. Garbage is embeded in upper-band bit-stream. + * That is the only way to preserve backward compatibility. */ + if ((instISAC->bandwidthKHz == isac8kHz) || + (streamLenUB == 0)) { + ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)garbageLen; + } else { + ptrEncodedUW8[streamLenLB] += (WebRtc_UWord8)garbageLen; + /* Write the length of the garbage at the end of the upper-band + * bit-stream, if exists. This helps for sanity check. */ + ptrEncodedUW8[streamLenLB + 1 + streamLenUB] = + (WebRtc_UWord8)garbageLen; + + } + streamLen += garbageLen; + } + } else { + /* update rate model */ + WebRtcIsac_UpdateRateModel( + &instISAC->rate_data_obj, streamLen, + instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck); + garbageLen = 0; + } + + /* Generate CRC if required. */ + if ((instISAC->bandwidthKHz != isac8kHz) && (streamLenUB > 0)) { + WebRtc_UWord32 crc; + + WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), + streamLenUB + garbageLen, &crc); #ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = - (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); - } -#else - memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, - LEN_CHECK_SUM_WORD8); -#endif + for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { + ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = + (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); } - +#else + memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, + LEN_CHECK_SUM_WORD8); +#endif + } return streamLen; } @@ -876,14 +748,12 @@ WebRtc_Word16 WebRtcIsac_Encode( * the struct since it is only allowed to read * the struct. */ -WebRtc_Word16 WebRtcIsac_GetNewBitStream( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 bweIndex, - WebRtc_Word16 jitterInfo, - WebRtc_Word32 rate, - WebRtc_Word16* encoded, - WebRtc_Word16 isRCU) -{ +WebRtc_Word16 WebRtcIsac_GetNewBitStream(ISACStruct* ISAC_main_inst, + WebRtc_Word16 bweIndex, + WebRtc_Word16 jitterInfo, + WebRtc_Word32 rate, + WebRtc_Word16* encoded, + WebRtc_Word16 isRCU) { Bitstr iSACBitStreamInst; /* Local struct for bitstream handling */ WebRtc_Word16 streamLenLB; WebRtc_Word16 streamLenUB; @@ -895,137 +765,108 @@ WebRtc_Word16 WebRtcIsac_GetNewBitStream( double rateLB; double rateUB; WebRtc_Word32 currentBN; - ISACMainStruct* instISAC; WebRtc_UWord8* encodedPtrUW8 = (WebRtc_UWord8*)encoded; WebRtc_UWord32 crc; #ifndef WEBRTC_BIG_ENDIAN WebRtc_Word16 k; #endif + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - instISAC = (ISACMainStruct*)ISAC_main_inst; + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + return -1; + } - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - return -1; - } - - // Get the bottleneck of this iSAC and limit the - // given rate to the current bottleneck. + /* Get the bottleneck of this iSAC and limit the + * given rate to the current bottleneck. */ WebRtcIsac_GetUplinkBw(ISAC_main_inst, ¤tBN); - if(rate > currentBN) - { - rate = currentBN; - } + if (rate > currentBN) { + rate = currentBN; + } - if(WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0) - { - return -1; - } + if (WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0) { + return -1; + } - // Cannot transcode from 16 kHz to 12 kHz - if((bandwidthKHz == isac12kHz) && - (instISAC->bandwidthKHz == isac16kHz)) - { - return -1; - } + /* Cannot transcode from 16 kHz to 12 kHz. */ + if ((bandwidthKHz == isac12kHz) && + (instISAC->bandwidthKHz == isac16kHz)) { + return -1; + } - // These gains are in dB - // gain for the given rate. - gain1 = WebRtcIsac_GetSnr(rateLB, - instISAC->instLB.ISACencLB_obj.current_framesamples); - // gain of this iSAC + /* A gain [dB] for the given rate. */ + gain1 = WebRtcIsac_GetSnr( + rateLB, instISAC->instLB.ISACencLB_obj.current_framesamples); + /* The gain [dB] of this iSAC. */ gain2 = WebRtcIsac_GetSnr( - instISAC->instLB.ISACencLB_obj.bottleneck, - instISAC->instLB.ISACencLB_obj.current_framesamples); + instISAC->instLB.ISACencLB_obj.bottleneck, + instISAC->instLB.ISACencLB_obj.current_framesamples); - // scale is the ratio of two gains in normal domain. + /* Scale is the ratio of two gains in normal domain. */ scale = (float)pow(10, (gain1 - gain2) / 20.0); - // change the scale if this is a RCU bit-stream. - scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE):scale; + /* Change the scale if this is a RCU bit-stream. */ + scale = (isRCU) ? (scale * RCU_TRANSCODING_SCALE) : scale; streamLenLB = WebRtcIsac_EncodeStoredDataLb( - &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, &iSACBitStreamInst, - bweIndex, scale); + &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, + &iSACBitStreamInst, bweIndex, scale); - if(streamLenLB < 0) - { - return -1; - } + if (streamLenLB < 0) { + return -1; + } - /* convert from bytes to WebRtc_Word16 */ + /* Convert from bytes to WebRtc_Word16. */ memcpy(encoded, iSACBitStreamInst.stream, streamLenLB); - if(bandwidthKHz == isac8kHz) - { - return streamLenLB; - } + if (bandwidthKHz == isac8kHz) { + return streamLenLB; + } totalStreamLen = streamLenLB; - // super-wideband is always at 30ms. - // These gains are in dB - // gain for the given rate. + /* super-wideband is always at 30ms. + * These gains are in dB. + * Gain for the given rate. */ gain1 = WebRtcIsac_GetSnr(rateUB, FRAMESAMPLES); - // gain of this iSAC - gain2 = WebRtcIsac_GetSnr( - instISAC->instUB.ISACencUB_obj.bottleneck, FRAMESAMPLES); + /* Gain of this iSAC */ + gain2 = WebRtcIsac_GetSnr(instISAC->instUB.ISACencUB_obj.bottleneck, + FRAMESAMPLES); - // scale is the ratio of two gains in normal domain. + /* Scale is the ratio of two gains in normal domain. */ scale = (float)pow(10, (gain1 - gain2) / 20.0); - // change the scale if this is a RCU bit-stream. - scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB):scale; + /* Change the scale if this is a RCU bit-stream. */ + scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB) : scale; - switch(instISAC->bandwidthKHz) - { - case isac12kHz: - { - streamLenUB = WebRtcIsac_EncodeStoredDataUb12( - &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), - &iSACBitStreamInst, jitterInfo, scale); - break; - } - case isac16kHz: - { - streamLenUB = WebRtcIsac_EncodeStoredDataUb16( - &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), - &iSACBitStreamInst, jitterInfo, scale); - break; - } - default: - return -1; - } + streamLenUB = WebRtcIsac_EncodeStoredDataUb( + &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), + &iSACBitStreamInst, jitterInfo, scale, + instISAC->bandwidthKHz); - if(streamLenUB < 0) - { - return -1; - } + if (streamLenUB < 0) { + return -1; + } - if(streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255) - { - return streamLenLB; - } + if (streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255) { + return streamLenLB; + } totalStreamLen = streamLenLB + streamLenUB + 1 + LEN_CHECK_SUM_WORD8; encodedPtrUW8[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; - memcpy(&encodedPtrUW8[streamLenLB+1], iSACBitStreamInst.stream, + memcpy(&encodedPtrUW8[streamLenLB + 1], iSACBitStreamInst.stream, streamLenUB); WebRtcIsac_GetCrc((WebRtc_Word16*)(&(encodedPtrUW8[streamLenLB + 1])), streamLenUB, &crc); #ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - encodedPtrUW8[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] = - (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); - } + for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { + encodedPtrUW8[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] = + (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); + } #else memcpy(&encodedPtrUW8[streamLenLB + streamLenUB + 1], &crc, LEN_CHECK_SUM_WORD8); #endif - - return totalStreamLen; } @@ -1046,77 +887,56 @@ WebRtc_Word16 WebRtcIsac_GetNewBitStream( * : 0 - Ok * -1 - Error */ -static WebRtc_Word16 DecoderInitLb( - ISACLBStruct* instISAC) -{ +static WebRtc_Word16 DecoderInitLb(ISACLBStruct* instISAC) { int i; - /* Init stream vector to zero */ - for (i=0; iISACdecLB_obj.bitstr_obj.stream[i] = 0; - } + /* Initialize stream vector to zero. */ + for (i = 0; i < STREAM_SIZE_MAX_60; i++) { + instISAC->ISACdecLB_obj.bitstr_obj.stream[i] = 0; + } WebRtcIsac_InitMasking(&instISAC->ISACdecLB_obj.maskfiltstr_obj); WebRtcIsac_InitPostFilterbank( - &instISAC->ISACdecLB_obj.postfiltbankstr_obj); + &instISAC->ISACdecLB_obj.postfiltbankstr_obj); WebRtcIsac_InitPitchFilter(&instISAC->ISACdecLB_obj.pitchfiltstr_obj); - - return (0); + return 0; } -static WebRtc_Word16 DecoderInitUb( - ISACUBStruct* instISAC) -{ +static WebRtc_Word16 DecoderInitUb(ISACUBStruct* instISAC) { int i; /* Init stream vector to zero */ - for (i = 0; i < STREAM_SIZE_MAX_60; i++) - { - instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0; - } + for (i = 0; i < STREAM_SIZE_MAX_60; i++) { + instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0; + } WebRtcIsac_InitMasking(&instISAC->ISACdecUB_obj.maskfiltstr_obj); WebRtcIsac_InitPostFilterbank( - &instISAC->ISACdecUB_obj.postfiltbankstr_obj); + &instISAC->ISACdecUB_obj.postfiltbankstr_obj); return (0); } -WebRtc_Word16 WebRtcIsac_DecoderInit( - ISACStruct *ISAC_main_inst) -{ - ISACMainStruct* instISAC; +WebRtc_Word16 WebRtcIsac_DecoderInit(ISACStruct* ISAC_main_inst) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - instISAC = (ISACMainStruct*)ISAC_main_inst; + if (DecoderInitLb(&instISAC->instLB) < 0) { + return -1; + } + if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) { + memset(instISAC->synthesisFBState1, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); + memset(instISAC->synthesisFBState2, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - if(DecoderInitLb(&instISAC->instLB) < 0) - { + if (DecoderInitUb(&(instISAC->instUB)) < 0) { return -1; } - - if(instISAC->decoderSamplingRateKHz == kIsacSuperWideband) - { - memset(instISAC->synthesisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->synthesisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - if(DecoderInitUb(&(instISAC->instUB)) < 0) - { - return -1; - } - } - - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, - instISAC->encoderSamplingRateKHz, - instISAC->decoderSamplingRateKHz); - } - + } + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) { + WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, + instISAC->encoderSamplingRateKHz, + instISAC->decoderSamplingRateKHz); + } instISAC->initFlag |= BIT_MASK_DEC_INIT; - instISAC->resetFlag_8kHz = 0; - return 0; } @@ -1137,409 +957,325 @@ WebRtc_Word16 WebRtcIsac_DecoderInit( * Return value : 0 - Ok * -1 - Error */ -WebRtc_Word16 WebRtcIsac_UpdateBwEstimate( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word32 packet_size, - WebRtc_UWord16 rtp_seq_number, - WebRtc_UWord32 send_ts, - WebRtc_UWord32 arr_ts) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_UpdateBwEstimate(ISACStruct* ISAC_main_inst, + const WebRtc_UWord16* encoded, + WebRtc_Word32 packet_size, + WebRtc_UWord16 rtp_seq_number, + WebRtc_UWord32 send_ts, + WebRtc_UWord32 arr_ts) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; Bitstr streamdata; #ifndef WEBRTC_BIG_ENDIAN int k; #endif WebRtc_Word16 err; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; + /* Check if decoder initiated. */ + if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != BIT_MASK_DEC_INIT) { + instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; + return -1; + } - /* check if decoder initiated */ - if((instISAC->initFlag & BIT_MASK_DEC_INIT) != - BIT_MASK_DEC_INIT) - { - instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; - return -1; - } + if (packet_size <= 0) { + /* Return error code if the packet length is null. */ + instISAC->errorCode = ISAC_EMPTY_PACKET; + return -1; + } - if(packet_size <= 0) - { - /* return error code if the packet length is null */ - instISAC->errorCode = ISAC_EMPTY_PACKET; - return -1; - } - - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; + WebRtcIsac_ResetBitstream(&(streamdata)); #ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < 10; k++) - { - streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >> - ((k&1) << 3)) & 0xFF); - } + for (k = 0; k < 10; k++) { + streamdata.stream[k] = (WebRtc_UWord8)((encoded[k >> 1] >> + ((k & 1) << 3)) & 0xFF); + } #else memcpy(streamdata.stream, encoded, 10); #endif err = WebRtcIsac_EstimateBandwidth(&instISAC->bwestimator_obj, &streamdata, - packet_size, rtp_seq_number, send_ts, arr_ts, - instISAC->encoderSamplingRateKHz, + packet_size, rtp_seq_number, send_ts, + arr_ts, instISAC->encoderSamplingRateKHz, instISAC->decoderSamplingRateKHz); - - if(err < 0) - { - /* return error code if something went wrong */ - instISAC->errorCode = -err; - return -1; - } - + if (err < 0) { + /* Return error code if something went wrong. */ + instISAC->errorCode = -err; + return -1; + } return 0; } -static WebRtc_Word16 Decode( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 lenEncodedBytes, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType, - WebRtc_Word16 isRCUPayload) -{ - /* number of samples (480 or 960), output from decoder +static WebRtc_Word16 Decode(ISACStruct* ISAC_main_inst, + const WebRtc_UWord16* encoded, + WebRtc_Word16 lenEncodedBytes, + WebRtc_Word16* decoded, + WebRtc_Word16* speechType, + WebRtc_Word16 isRCUPayload) { + /* Number of samples (480 or 960), output from decoder that were actually used in the encoder/decoder - (determined on the fly) */ - ISACMainStruct* instISAC; - ISACUBDecStruct* decInstUB; - ISACLBDecStruct* decInstLB; - - WebRtc_Word16 numSamplesLB; - WebRtc_Word16 numSamplesUB; - WebRtc_Word16 speechIdx; - float outFrame[MAX_FRAMESAMPLES]; - WebRtc_Word16 outFrameLB[MAX_FRAMESAMPLES]; - WebRtc_Word16 outFrameUB[MAX_FRAMESAMPLES]; - WebRtc_Word16 numDecodedBytesLB; - WebRtc_Word16 numDecodedBytesUB; - WebRtc_Word16 lenEncodedLBBytes; - WebRtc_Word16 validChecksum = 1; - WebRtc_Word16 k; + (determined on the fly). */ + WebRtc_Word16 numSamplesLB; + WebRtc_Word16 numSamplesUB; + WebRtc_Word16 speechIdx; + float outFrame[MAX_FRAMESAMPLES]; + WebRtc_Word16 outFrameLB[MAX_FRAMESAMPLES]; + WebRtc_Word16 outFrameUB[MAX_FRAMESAMPLES]; + WebRtc_Word16 numDecodedBytesLB; + WebRtc_Word16 numDecodedBytesUB; + WebRtc_Word16 lenEncodedLBBytes; + WebRtc_Word16 validChecksum = 1; + WebRtc_Word16 k; WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; WebRtc_UWord16 numLayer; - WebRtc_Word16 totSizeBytes; - WebRtc_Word16 err; + WebRtc_Word16 totSizeBytes; + WebRtc_Word16 err; - instISAC = (ISACMainStruct*)ISAC_main_inst; - decInstUB = &(instISAC->instUB.ISACdecUB_obj); - decInstLB = &(instISAC->instLB.ISACdecLB_obj); + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; + ISACUBDecStruct* decInstUB = &(instISAC->instUB.ISACdecUB_obj); + ISACLBDecStruct* decInstLB = &(instISAC->instLB.ISACdecLB_obj); - /* check if decoder initiated */ - if((instISAC->initFlag & BIT_MASK_DEC_INIT) != - BIT_MASK_DEC_INIT) - { - instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; - return -1; - } + /* Check if decoder initiated. */ + if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != + BIT_MASK_DEC_INIT) { + instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; + return -1; + } - if(lenEncodedBytes <= 0) - { - /* return error code if the packet length is null */ - instISAC->errorCode = ISAC_EMPTY_PACKET; - return -1; - } + if (lenEncodedBytes <= 0) { + /* return error code if the packet length is null. */ + instISAC->errorCode = ISAC_EMPTY_PACKET; + return -1; + } - // the size of the rncoded lower-band is bounded by - // STREAM_SIZE_MAX, - // If a payload with the size larger than STREAM_SIZE_MAX - // is received, it is not considered erroneous. - lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX) - ? STREAM_SIZE_MAX:lenEncodedBytes; + /* The size of the encoded lower-band is bounded by + * STREAM_SIZE_MAX. If a payload with the size larger than STREAM_SIZE_MAX + * is received, it is not considered erroneous. */ + lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX) ? + STREAM_SIZE_MAX : lenEncodedBytes; - // Copy to lower-band bit-stream structure + /* Copy to lower-band bit-stream structure. */ memcpy(instISAC->instLB.ISACdecLB_obj.bitstr_obj.stream, ptrEncodedUW8, lenEncodedLBBytes); - // Regardless of that the current codec is setup to work in - // wideband or super-wideband, the decoding of the lower-band - // has to be performed. + /* Regardless of that the current codec is setup to work in + * wideband or super-wideband, the decoding of the lower-band + * has to be performed. */ numDecodedBytesLB = WebRtcIsac_DecodeLb(outFrame, decInstLB, &numSamplesLB, isRCUPayload); - // Check for error - if((numDecodedBytesLB < 0) || - (numDecodedBytesLB > lenEncodedLBBytes) || - (numSamplesLB > MAX_FRAMESAMPLES)) - { + if ((numDecodedBytesLB < 0) || (numDecodedBytesLB > lenEncodedLBBytes) || + (numSamplesLB > MAX_FRAMESAMPLES)) { + instISAC->errorCode = ISAC_LENGTH_MISMATCH; + return -1; + } + + /* Error Check, we accept multi-layer bit-stream This will limit number + * of iterations of the while loop. Even without this the number + * of iterations is limited. */ + numLayer = 1; + totSizeBytes = numDecodedBytesLB; + while (totSizeBytes != lenEncodedBytes) { + if ((totSizeBytes > lenEncodedBytes) || + (ptrEncodedUW8[totSizeBytes] == 0) || + (numLayer > MAX_NUM_LAYERS)) { instISAC->errorCode = ISAC_LENGTH_MISMATCH; return -1; } + totSizeBytes += ptrEncodedUW8[totSizeBytes]; + numLayer++; + } - // Error Check, we accept multi-layer bit-stream - // This will limit number of iterations of the - // while loop. Even withouut this the number of iterations - // is limited. - numLayer = 1; - totSizeBytes = numDecodedBytesLB; - while(totSizeBytes != lenEncodedBytes) - { - if((totSizeBytes > lenEncodedBytes) || - (ptrEncodedUW8[totSizeBytes] == 0) || - (numLayer > MAX_NUM_LAYERS)) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - totSizeBytes += ptrEncodedUW8[totSizeBytes]; - numLayer++; + if (instISAC->decoderSamplingRateKHz == kIsacWideband) { + for (k = 0; k < numSamplesLB; k++) { + if (outFrame[k] > 32767) { + decoded[k] = 32767; + } else if (outFrame[k] < -32768) { + decoded[k] = -32768; + } else { + decoded[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); + } + } + numSamplesUB = 0; + } else { + WebRtc_UWord32 crc; + /* We don't accept larger than 30ms (480 samples at lower-band) + * frame-size. */ + for (k = 0; k < numSamplesLB; k++) { + if (outFrame[k] > 32767) { + outFrameLB[k] = 32767; + } else if (outFrame[k] < -32768) { + outFrameLB[k] = -32768; + } else { + outFrameLB[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); + } } - if(instISAC->decoderSamplingRateKHz == kIsacWideband) - { - for(k = 0; k < numSamplesLB; k++) - { - if(outFrame[k] > 32767) - { - decoded[k] = 32767; - } - else if(outFrame[k] < -32768) - { - decoded[k] = -32768; - } - else - { - decoded[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); - } - } - numSamplesUB = 0; + /* Check for possible error, and if upper-band stream exists. */ + if (numDecodedBytesLB == lenEncodedBytes) { + /* Decoding was successful. No super-wideband bit-stream exists. */ + numSamplesUB = numSamplesLB; + memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); + + /* Prepare for the potential increase of signal bandwidth. */ + instISAC->resetFlag_8kHz = 2; + } else { + /* This includes the checksum and the bytes that stores the length. */ + WebRtc_Word16 lenNextStream = ptrEncodedUW8[numDecodedBytesLB]; + + /* Is this garbage or valid super-wideband bit-stream? + * Check if checksum is valid. */ + if (lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1)) { + /* Such a small second layer cannot be super-wideband layer. + * It must be a short garbage. */ + validChecksum = 0; + } else { + /* Run CRC to see if the checksum match. */ + WebRtcIsac_GetCrc((WebRtc_Word16*)( + &ptrEncodedUW8[numDecodedBytesLB + 1]), + lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc); + + validChecksum = 1; + for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { + validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) == + ptrEncodedUW8[numDecodedBytesLB + lenNextStream - + LEN_CHECK_SUM_WORD8 + k]); + } + } + + if (!validChecksum) { + /* This is a garbage, we have received a wideband + * bit-stream with garbage. */ + numSamplesUB = numSamplesLB; + memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); + } else { + /* A valid super-wideband biststream exists. */ + enum ISACBandwidth bandwidthKHz; + WebRtc_Word32 maxDelayBit; + + /* If we have super-wideband bit-stream, we cannot + * have 60 ms frame-size. */ + if (numSamplesLB > FRAMESAMPLES) { + instISAC->errorCode = ISAC_LENGTH_MISMATCH; + return -1; + } + + /* The rest of the bit-stream contains the upper-band + * bit-stream curently this is the only thing there, + * however, we might add more layers. */ + + /* Have to exclude one byte where the length is stored + * and last 'LEN_CHECK_SUM_WORD8' bytes where the + * checksum is stored. */ + lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1); + + memcpy(decInstUB->bitstr_obj.stream, + &ptrEncodedUW8[numDecodedBytesLB + 1], lenNextStream); + + /* Reset bit-stream object, this is the first decoding. */ + WebRtcIsac_ResetBitstream(&(decInstUB->bitstr_obj)); + + /* Decode jitter information. */ + err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, &maxDelayBit); + if (err < 0) { + instISAC->errorCode = -err; + return -1; + } + + /* Update jitter info which is in the upper-band bit-stream + * only if the encoder is in super-wideband. Otherwise, + * the jitter info is already embedded in bandwidth index + * and has been updated. */ + if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { + err = WebRtcIsac_UpdateUplinkJitter( + &(instISAC->bwestimator_obj), maxDelayBit); + if (err < 0) { + instISAC->errorCode = -err; + return -1; + } + } + + /* Decode bandwidth information. */ + err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj, + &bandwidthKHz); + if (err < 0) { + instISAC->errorCode = -err; + return -1; + } + + switch (bandwidthKHz) { + case isac12kHz: { + numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame, decInstUB, + isRCUPayload); + + /* Hang-over for transient alleviation - + * wait two frames to add the upper band going up from 8 kHz. */ + if (instISAC->resetFlag_8kHz > 0) { + if (instISAC->resetFlag_8kHz == 2) { + /* Silence first and a half frame. */ + memset(outFrame, 0, MAX_FRAMESAMPLES * + sizeof(float)); + } else { + const float rampStep = 2.0f / MAX_FRAMESAMPLES; + float rampVal = 0; + memset(outFrame, 0, (MAX_FRAMESAMPLES >> 1) * + sizeof(float)); + + /* Ramp up second half of second frame. */ + for (k = MAX_FRAMESAMPLES / 2; k < MAX_FRAMESAMPLES; k++) { + outFrame[k] *= rampVal; + rampVal += rampStep; + } + } + instISAC->resetFlag_8kHz -= 1; + } + + break; + } + case isac16kHz: { + numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame, decInstUB, + isRCUPayload); + break; + } + default: + return -1; + } + + /* It might be less due to garbage. */ + if ((numDecodedBytesUB != lenNextStream) && + (numDecodedBytesUB != (lenNextStream - + ptrEncodedUW8[numDecodedBytesLB + 1 + numDecodedBytesUB]))) { + instISAC->errorCode = ISAC_LENGTH_MISMATCH; + return -1; + } + + /* If there is no error Upper-band always decodes + * 30 ms (480 samples). */ + numSamplesUB = FRAMESAMPLES; + + /* Convert to W16. */ + for (k = 0; k < numSamplesUB; k++) { + if (outFrame[k] > 32767) { + outFrameUB[k] = 32767; + } else if (outFrame[k] < -32768) { + outFrameUB[k] = -32768; + } else { + outFrameUB[k] = (WebRtc_Word16)WebRtcIsac_lrint( + outFrame[k]); + } + } + } } - else - { - WebRtc_UWord32 crc; - // We don't accept larger than 30ms (480 samples at lower-band) - // frame-size. - for(k = 0; k < numSamplesLB; k++) - { - if(outFrame[k] > 32767) - { - outFrameLB[k] = 32767; - } - else if(outFrame[k] < -32768) - { - outFrameLB[k] = -32768; - } - else - { - outFrameLB[k] = (WebRtc_Word16)WebRtcIsac_lrint(outFrame[k]); - } - } - //numSamplesUB = numSamplesLB; + speechIdx = 0; + while (speechIdx < numSamplesLB) { + WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], &outFrameUB[speechIdx], + &decoded[(speechIdx << 1)], + instISAC->synthesisFBState1, + instISAC->synthesisFBState2); - // Check for possible error, and if upper-band stream exist. - if(numDecodedBytesLB == lenEncodedBytes) - { - // Decoding was successful. No super-wideband bitstream - // exists. - numSamplesUB = numSamplesLB; - memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); - - // Prepare for the potential increase of signal bandwidth - instISAC->resetFlag_8kHz = 2; - } - else - { - // this includes the check sum and the bytes that stores the - // length - WebRtc_Word16 lenNextStream = ptrEncodedUW8[numDecodedBytesLB]; - - // Is this garbage or valid super-wideband bit-stream? - // Check if checksum is valid - if(lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1)) - { - // such a small second layer cannot be super-wideband layer. - // It must be a short garbage. - validChecksum = 0; - } - else - { - // Run CRC to see if the checksum match. - WebRtcIsac_GetCrc((WebRtc_Word16*)( - &ptrEncodedUW8[numDecodedBytesLB + 1]), - lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc); - - validChecksum = 1; - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) == - ptrEncodedUW8[numDecodedBytesLB + lenNextStream - - LEN_CHECK_SUM_WORD8 + k]); - } - } - - if(!validChecksum) - { - // this is a garbage, we have received a wideband - // bit-stream with garbage - numSamplesUB = numSamplesLB; - memset(outFrameUB, 0, sizeof(WebRtc_Word16) * numSamplesUB); - } - else - { - // A valid super-wideband biststream exists. - enum ISACBandwidth bandwidthKHz; - WebRtc_Word32 maxDelayBit; - - //instISAC->bwestimator_obj.incomingStreamSampFreq = - // kIsacSuperWideband; - // If we have super-wideband bit-stream, we cannot - // have 60 ms frame-size. - if(numSamplesLB > FRAMESAMPLES) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - - // the rest of the bit-stream contains the upper-band - // bit-stream curently this is the only thing there, - // however, we might add more layers. - - // Have to exclude one byte where the length is stored - // and last 'LEN_CHECK_SUM_WORD8' bytes where the - // checksum is stored. - lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1); - - memcpy(decInstUB->bitstr_obj.stream, - &ptrEncodedUW8[numDecodedBytesLB + 1], lenNextStream); - - // THIS IS THE FIRST DECODING - decInstUB->bitstr_obj.W_upper = 0xFFFFFFFF; - decInstUB->bitstr_obj.streamval = 0; - decInstUB->bitstr_obj.stream_index = 0; - - // Decode jitter infotmation - err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, - &maxDelayBit); - // error check - if(err < 0) - { - instISAC->errorCode = -err; - return -1; - } - - // Update jitter info which is in the upper-band bit-stream - // only if the encoder is in super-wideband. Otherwise, - // the jitter info is already embeded in bandwidth index - // and has been updated. - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - err = WebRtcIsac_UpdateUplinkJitter( - &(instISAC->bwestimator_obj), maxDelayBit); - if(err < 0) - { - instISAC->errorCode = -err; - return -1; - } - } - - // decode bandwidth information - err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj, - &bandwidthKHz); - if(err < 0) - { - instISAC->errorCode = -err; - return -1; - } - - switch(bandwidthKHz) - { - case isac12kHz: - { - numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame, - decInstUB, isRCUPayload); - - // Hang-over for transient alleviation - - // wait two frames to add the upper band going up from 8 kHz - if (instISAC->resetFlag_8kHz > 0) - { - if (instISAC->resetFlag_8kHz == 2) - { - // Silence first and a half frame - memset(outFrame, 0, MAX_FRAMESAMPLES * - sizeof(float)); - } - else - { - const float rampStep = 2.0f / MAX_FRAMESAMPLES; - float rampVal = 0; - memset(outFrame, 0, (MAX_FRAMESAMPLES>>1) * - sizeof(float)); - - // Ramp up second half of second frame - for(k = MAX_FRAMESAMPLES/2; k < MAX_FRAMESAMPLES; k++) - { - outFrame[k] *= rampVal; - rampVal += rampStep; - } - } - instISAC->resetFlag_8kHz -= 1; - } - - break; - } - case isac16kHz: - { - numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame, - decInstUB, isRCUPayload); - break; - } - default: - return -1; - } - - // it might be less due to garbage. - if((numDecodedBytesUB != lenNextStream) && - (numDecodedBytesUB != (lenNextStream - ptrEncodedUW8[ - numDecodedBytesLB + 1 + numDecodedBytesUB]))) - { - instISAC->errorCode = ISAC_LENGTH_MISMATCH; - return -1; - } - - // If there is no error Upper-band always decodes - // 30 ms (480 samples) - numSamplesUB = FRAMESAMPLES; - - // Convert to W16 - for(k = 0; k < numSamplesUB; k++) - { - if(outFrame[k] > 32767) - { - outFrameUB[k] = 32767; - } - else if(outFrame[k] < -32768) - { - outFrameUB[k] = -32768; - } - else - { - outFrameUB[k] = (WebRtc_Word16)WebRtcIsac_lrint( - outFrame[k]); - } - } - } - } - - speechIdx = 0; - while(speechIdx < numSamplesLB) - { - WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], - &outFrameUB[speechIdx], &decoded[(speechIdx<<1)], - instISAC->synthesisFBState1, instISAC->synthesisFBState2); - - speechIdx += FRAMESAMPLES_10ms; - } + speechIdx += FRAMESAMPLES_10ms; } + } *speechType = 0; return (numSamplesLB + numSamplesUB); } @@ -1569,23 +1305,21 @@ static WebRtc_Word16 Decode( * -1 - Error */ -WebRtc_Word16 WebRtcIsac_Decode( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 lenEncodedBytes, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType) -{ +WebRtc_Word16 WebRtcIsac_Decode(ISACStruct* ISAC_main_inst, + const WebRtc_UWord16* encoded, + WebRtc_Word16 lenEncodedBytes, + WebRtc_Word16* decoded, + WebRtc_Word16* speechType) { WebRtc_Word16 isRCUPayload = 0; return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, - speechType, isRCUPayload); + speechType, isRCUPayload); } /**************************************************************************** * WebRtcIsac_DecodeRcu(...) * * This function decodes a redundant (RCU) iSAC frame. Function is called in - * NetEq with a stored RCU payload i case of packet loss. Output speech length + * NetEq with a stored RCU payload in case of packet loss. Output speech length * will be a multiple of 480 samples: 480 or 960 samples, * depending on the framesize (30 or 60 ms). * @@ -1603,16 +1337,14 @@ WebRtc_Word16 WebRtcIsac_Decode( -WebRtc_Word16 WebRtcIsac_DecodeRcu( - ISACStruct* ISAC_main_inst, - const WebRtc_UWord16* encoded, - WebRtc_Word16 lenEncodedBytes, - WebRtc_Word16* decoded, - WebRtc_Word16* speechType) -{ +WebRtc_Word16 WebRtcIsac_DecodeRcu(ISACStruct* ISAC_main_inst, + const WebRtc_UWord16* encoded, + WebRtc_Word16 lenEncodedBytes, + WebRtc_Word16* decoded, + WebRtc_Word16* speechType) { WebRtc_Word16 isRCUPayload = 1; return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, - speechType, isRCUPayload); + speechType, isRCUPayload); } @@ -1633,48 +1365,39 @@ WebRtc_Word16 WebRtcIsac_DecodeRcu( * Return value : >0 - number of samples in decoded PLC vector * -1 - Error */ -WebRtc_Word16 WebRtcIsac_DecodePlc( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* decoded, - WebRtc_Word16 noOfLostFrames) -{ +WebRtc_Word16 WebRtcIsac_DecodePlc(ISACStruct* ISAC_main_inst, + WebRtc_Word16* decoded, + WebRtc_Word16 noOfLostFrames) { WebRtc_Word16 numSamples = 0; - ISACMainStruct* instISAC; + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; - - /* Limit number of frames to two = 60 msec. Otherwise we exceed data vectors */ - if(noOfLostFrames > 2) - { - noOfLostFrames = 2; - } + /* Limit number of frames to two = 60 millisecond. + * Otherwise we exceed data vectors. */ + if (noOfLostFrames > 2) { + noOfLostFrames = 2; + } /* Get the number of samples per frame */ - switch(instISAC->decoderSamplingRateKHz) - { - case kIsacWideband: - { - numSamples = 480 * noOfLostFrames; - break; - } - case kIsacSuperWideband: - { - numSamples = 960 * noOfLostFrames; - break; - } + switch (instISAC->decoderSamplingRateKHz) { + case kIsacWideband: { + numSamples = 480 * noOfLostFrames; + break; } + case kIsacSuperWideband: { + numSamples = 960 * noOfLostFrames; + break; + } + } - /* Set output samples to zero */ + /* Set output samples to zero. */ memset(decoded, 0, numSamples * sizeof(WebRtc_Word16)); return numSamples; } /**************************************************************************** - * ControlLb(...) - Internal function for controling Lower Band - * ControlUb(...) - Internal function for controling Upper Band + * ControlLb(...) - Internal function for controlling Lower Band + * ControlUb(...) - Internal function for controlling Upper Band * WebRtcIsac_Control(...) - API function * * This function sets the limit on the short-term average bit rate and the @@ -1684,156 +1407,119 @@ WebRtc_Word16 WebRtcIsac_DecodePlc( * - ISAC_main_inst : ISAC instance. * - rate : limit on the short-term average bit rate, * in bits/second (between 10000 and 32000) - * - frameSize : number of milliseconds per frame (30 or 60) + * - frameSize : number of milliseconds per frame (30 or 60) * - * Return value : 0 - ok + * Return value : 0 - ok * -1 - Error */ -static WebRtc_Word16 ControlLb( - ISACLBStruct* instISAC, - double rate, - WebRtc_Word16 frameSize) -{ - if((rate >= 10000) && (rate <= 32000)) - { - instISAC->ISACencLB_obj.bottleneck = rate; - } - else - { - return -ISAC_DISALLOWED_BOTTLENECK; - } +static WebRtc_Word16 ControlLb(ISACLBStruct* instISAC, double rate, + WebRtc_Word16 frameSize) { + if ((rate >= 10000) && (rate <= 32000)) { + instISAC->ISACencLB_obj.bottleneck = rate; + } else { + return -ISAC_DISALLOWED_BOTTLENECK; + } - if((frameSize == 30) || (frameSize == 60)) - { - instISAC->ISACencLB_obj.new_framelength = (FS/1000) * frameSize; - } - else - { - return -ISAC_DISALLOWED_FRAME_LENGTH; - } + if ((frameSize == 30) || (frameSize == 60)) { + instISAC->ISACencLB_obj.new_framelength = (FS / 1000) * frameSize; + } else { + return -ISAC_DISALLOWED_FRAME_LENGTH; + } return 0; } -static WebRtc_Word16 ControlUb( - ISACUBStruct* instISAC, - double rate) -{ - if((rate >= 10000) && (rate <= 32000)) - { - instISAC->ISACencUB_obj.bottleneck = rate; - } - else - { - return -ISAC_DISALLOWED_BOTTLENECK; - } +static WebRtc_Word16 ControlUb(ISACUBStruct* instISAC, double rate) { + if ((rate >= 10000) && (rate <= 32000)) { + instISAC->ISACencUB_obj.bottleneck = rate; + } else { + return -ISAC_DISALLOWED_BOTTLENECK; + } return 0; } -WebRtc_Word16 WebRtcIsac_Control( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 bottleneckBPS, - WebRtc_Word16 frameSize) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_Control(ISACStruct* ISAC_main_inst, + WebRtc_Word32 bottleneckBPS, + WebRtc_Word16 frameSize) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; WebRtc_Word16 status; double rateLB; double rateUB; enum ISACBandwidth bandwidthKHz; + if (instISAC->codingMode == 0) { + /* In adaptive mode. */ + instISAC->errorCode = ISAC_MODE_MISMATCH; + return -1; + } - /* Typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; + /* Check if encoder initiated */ + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } - if(instISAC->codingMode == 0) - { - /* in adaptive mode */ - instISAC->errorCode = ISAC_MODE_MISMATCH; + if (instISAC->encoderSamplingRateKHz == kIsacWideband) { + /* If the sampling rate is 16kHz then bandwith should be 8kHz, + * regardless of bottleneck. */ + bandwidthKHz = isac8kHz; + rateLB = (bottleneckBPS > 32000) ? 32000 : bottleneckBPS; + rateUB = 0; + } else { + if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, + &bandwidthKHz) < 0) { return -1; } + } - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - // if the sampling rate is 16kHz then bandwith should be 8kHz, - // regardless of bottleneck. - bandwidthKHz = isac8kHz; - rateLB = (bottleneckBPS > 32000)? 32000:bottleneckBPS; - rateUB = 0; - } - else - { - if(WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, - &bandwidthKHz) < 0) - { - return -1; - } - } - - if((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) && - (frameSize != 30) && - (bandwidthKHz != isac8kHz)) - { - // Cannot have 60 ms in super-wideband - instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; - return -1; - } + if ((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) && + (frameSize != 30) && + (bandwidthKHz != isac8kHz)) { + /* Cannot have 60 ms in super-wideband. */ + instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; + return -1; + } status = ControlLb(&instISAC->instLB, rateLB, frameSize); - if(status < 0) - { + if (status < 0) { + instISAC->errorCode = -status; + return -1; + } + if (bandwidthKHz != isac8kHz) { + status = ControlUb(&(instISAC->instUB), rateUB); + if (status < 0) { instISAC->errorCode = -status; return -1; } - if(bandwidthKHz != isac8kHz) - { - status = ControlUb(&(instISAC->instUB), rateUB); - if(status < 0) - { - instISAC->errorCode = -status; - return -1; - } + } + + + /* Check if bandwidth is changing from wideband to super-wideband + * then we have to synch data buffer of lower & upper-band. Also + * clean up the upper-band data buffer. */ + + if ((instISAC->bandwidthKHz == isac8kHz) && (bandwidthKHz != isac8kHz)) { + memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0, + sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES)); + + if (bandwidthKHz == isac12kHz) { + instISAC->instUB.ISACencUB_obj.buffer_index = + instISAC->instLB.ISACencLB_obj.buffer_index; + } else { + instISAC->instUB.ISACencUB_obj.buffer_index = + LB_TOTAL_DELAY_SAMPLES + instISAC->instLB.ISACencLB_obj.buffer_index; + + memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec), + WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); } + } - // - // Check if bandwidth is changing from wideband to super-wideband - // then we have to synch data buffer of lower & upper-band. also - // clean up the upper-band data buffer. - // - if((instISAC->bandwidthKHz == isac8kHz) && - (bandwidthKHz != isac8kHz)) - { - memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0, - sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES)); - - if(bandwidthKHz == isac12kHz) - { - instISAC->instUB.ISACencUB_obj.buffer_index = - instISAC->instLB.ISACencLB_obj.buffer_index; - } - else - { - instISAC->instUB.ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES + - instISAC->instLB.ISACencLB_obj.buffer_index; - - memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec), - WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); - } - } - - // update the payload limit it the bandwidth is changing. - if(instISAC->bandwidthKHz != bandwidthKHz) - { - instISAC->bandwidthKHz = bandwidthKHz; - UpdatePayloadSizeLimit(instISAC); - } + /* Update the payload limit if the bandwidth is changing. */ + if (instISAC->bandwidthKHz != bandwidthKHz) { + instISAC->bandwidthKHz = bandwidthKHz; + UpdatePayloadSizeLimit(instISAC); + } instISAC->bottleneck = bottleneckBPS; return 0; } @@ -1858,84 +1544,65 @@ WebRtc_Word16 WebRtcIsac_Control( * the adaptation process, 0 to let iSAC change * the frame-size if required. * - * Return value : 0 - ok + * Return value : 0 - ok * -1 - Error */ -WebRtc_Word16 WebRtcIsac_ControlBwe( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 bottleneckBPS, - WebRtc_Word16 frameSizeMs, - WebRtc_Word16 enforceFrameSize) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_ControlBwe(ISACStruct* ISAC_main_inst, + WebRtc_Word32 bottleneckBPS, + WebRtc_Word16 frameSizeMs, + WebRtc_Word16 enforceFrameSize) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; enum ISACBandwidth bandwidth; - /* Typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } + /* Check if encoder initiated */ + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } /* Check that we are in channel-adaptive mode, otherwise, return (-1) */ - if(instISAC->codingMode != 0) - { - instISAC->errorCode = ISAC_MODE_MISMATCH; + if (instISAC->codingMode != 0) { + instISAC->errorCode = ISAC_MODE_MISMATCH; + return -1; + } + if ((frameSizeMs != 30) && + (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { + return -1; + } + + /* Set structure variable if enforceFrameSize is set. ISAC will then + * keep the chosen frame size. */ + if (enforceFrameSize != 0) { + instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1; + } else { + instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0; + } + + /* Set the initial rate. If the input value is zero then the default intial + * rate is used. Otehrwise, values between 10 to 32 kbps are accepted. */ + if (bottleneckBPS != 0) { + double rateLB; + double rateUB; + if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, + &bandwidth) < 0) { return -1; } - if((frameSizeMs != 30) && - (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) - { + instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS; + instISAC->bandwidthKHz = bandwidth; + } + + /* Set the initial frame-size. If 'enforceFrameSize' is set, the frame-size + * will not change */ + if (frameSizeMs != 0) { + if ((frameSizeMs == 30) || (frameSizeMs == 60)) { + instISAC->instLB.ISACencLB_obj.new_framelength = (FS / 1000) * + frameSizeMs; + } else { + instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; return -1; } - - /* Set struct variable if enforceFrameSize is set. ISAC will then */ - /* keep the chosen frame size. */ - if((enforceFrameSize != 0) /*|| - (instISAC->samplingRateKHz == kIsacSuperWideband)*/) - { - instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1; - } - else - { - instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0; - } - - /* Set initial rate, if value between 10000 and 32000, */ - /* if rateBPS is 0, keep the default initial bottleneck value (15000) */ - if(bottleneckBPS != 0) - { - double rateLB; - double rateUB; - if(WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, &bandwidth) < 0) - { - return -1; - } - instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS; - instISAC->bandwidthKHz = bandwidth; - } - - /* Set initial frameSize. If enforceFrameSize is set the frame size will - not change */ - if(frameSizeMs != 0) - { - if((frameSizeMs == 30) || (frameSizeMs == 60)) - { - instISAC->instLB.ISACencLB_obj.new_framelength = (FS/1000) * - frameSizeMs; - //instISAC->bwestimator_obj.rec_header_rate = ((float)HEADER_SIZE * - // 8.0f * 1000.0f / (float)frameSizeMs); - } - else - { - instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; - return -1; - } - } + } return 0; } @@ -1944,36 +1611,31 @@ WebRtc_Word16 WebRtcIsac_ControlBwe( * WebRtcIsac_GetDownLinkBwIndex(...) * * This function returns index representing the Bandwidth estimate from - * other side to this side. + * the other side to this side. * * Input: - * - ISAC_main_inst : iSAC struct + * - ISAC_main_inst : iSAC structure * * Output: * - bweIndex : Bandwidth estimate to transmit to other side. * */ -WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* bweIndex, - WebRtc_Word16* jitterInfo) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex(ISACStruct* ISAC_main_inst, + WebRtc_Word16* bweIndex, + WebRtc_Word16* jitterInfo) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; + /* Check if encoder initialized. */ + if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != + BIT_MASK_DEC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_DEC_INIT) != - BIT_MASK_DEC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - /* Call function to get Bandwidth Estimate */ - WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), - bweIndex, jitterInfo, instISAC->decoderSamplingRateKHz); + /* Call function to get Bandwidth Estimate. */ + WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), bweIndex, + jitterInfo, + instISAC->decoderSamplingRateKHz); return 0; } @@ -1985,44 +1647,35 @@ WebRtc_Word16 WebRtcIsac_GetDownLinkBwIndex( * this side to other side and updates BWE. * * Input: - * - ISAC_main_inst : iSAC struct + * - ISAC_main_inst : iSAC structure * - rateIndex : Bandwidth estimate from other side. * * Return value : 0 - ok * -1 - index out of range */ -WebRtc_Word16 WebRtcIsac_UpdateUplinkBw( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 bweIndex) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_UpdateUplinkBw(ISACStruct* ISAC_main_inst, + WebRtc_Word16 bweIndex) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; WebRtc_Word16 returnVal; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; + /* Check if encoder initiated. */ + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - - /* Call function to get Bandwidth Estimate */ + /* Call function to get Bandwidth Estimate. */ returnVal = WebRtcIsac_UpdateUplinkBwImpl( - &(instISAC->bwestimator_obj), bweIndex, - instISAC->encoderSamplingRateKHz); + &(instISAC->bwestimator_obj), bweIndex, + instISAC->encoderSamplingRateKHz); - if(returnVal < 0) - { - instISAC->errorCode = -returnVal; - return -1; - } - else - { - return 0; - } + if (returnVal < 0) { + instISAC->errorCode = -returnVal; + return -1; + } else { + return 0; + } } @@ -2030,53 +1683,46 @@ WebRtc_Word16 WebRtcIsac_UpdateUplinkBw( * WebRtcIsac_ReadBwIndex(...) * * This function returns the index of the Bandwidth estimate from the - * bitstream. + * bit-stream. * * Input: - * - encoded : Encoded bitstream + * - encoded : Encoded bit-stream * * Output: * - frameLength : Length of frame in packet (in samples) - * - bweIndex : Bandwidth estimate in bitstream + * - bweIndex : Bandwidth estimate in bit-stream * */ -WebRtc_Word16 WebRtcIsac_ReadBwIndex( - const WebRtc_Word16* encoded, - WebRtc_Word16* bweIndex) -{ +WebRtc_Word16 WebRtcIsac_ReadBwIndex(const WebRtc_Word16* encoded, + WebRtc_Word16* bweIndex) { Bitstr streamdata; #ifndef WEBRTC_BIG_ENDIAN int k; #endif WebRtc_Word16 err; - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; + WebRtcIsac_ResetBitstream(&(streamdata)); #ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < 10; k++) - { - streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >> - ((k&1) << 3)) & 0xFF); - } + for (k = 0; k < 10; k++) { + streamdata.stream[k] = (WebRtc_UWord8)((encoded[k >> 1] >> + ((k & 1) << 3)) & 0xFF); + } #else memcpy(streamdata.stream, encoded, 10); #endif - /* decode frame length */ + /* Decode frame length. */ err = WebRtcIsac_DecodeFrameLen(&streamdata, bweIndex); - if(err < 0) - { - return err; - } + if (err < 0) { + return err; + } - /* decode BW estimation */ + /* Decode BW estimation. */ err = WebRtcIsac_DecodeSendBW(&streamdata, bweIndex); - if(err < 0) - { - return err; - } + if (err < 0) { + return err; + } return 0; } @@ -2094,11 +1740,9 @@ WebRtc_Word16 WebRtcIsac_ReadBwIndex( * - frameLength : Length of frame in packet (in samples) * */ -WebRtc_Word16 WebRtcIsac_ReadFrameLen( - ISACStruct* ISAC_main_inst, - const WebRtc_Word16* encoded, - WebRtc_Word16* frameLength) -{ +WebRtc_Word16 WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst, + const WebRtc_Word16* encoded, + WebRtc_Word16* frameLength) { Bitstr streamdata; #ifndef WEBRTC_BIG_ENDIAN int k; @@ -2106,34 +1750,30 @@ WebRtc_Word16 WebRtcIsac_ReadFrameLen( WebRtc_Word16 err; ISACMainStruct* instISAC; - streamdata.W_upper = 0xFFFFFFFF; - streamdata.streamval = 0; - streamdata.stream_index = 0; + WebRtcIsac_ResetBitstream(&(streamdata)); #ifndef WEBRTC_BIG_ENDIAN - for (k=0; k<10; k++) { - streamdata.stream[k] = (WebRtc_UWord8) ((encoded[k>>1] >> - ((k&1) << 3)) & 0xFF); + for (k = 0; k < 10; k++) { + streamdata.stream[k] = (WebRtc_UWord8)((encoded[k >> 1] >> + ((k & 1) << 3)) & 0xFF); } #else memcpy(streamdata.stream, encoded, 10); #endif - /* decode frame length */ + /* Decode frame length. */ err = WebRtcIsac_DecodeFrameLen(&streamdata, frameLength); - if(err < 0) { + if (err < 0) { return -1; } instISAC = (ISACMainStruct*)ISAC_main_inst; - if(instISAC->decoderSamplingRateKHz == kIsacSuperWideband) - { - // the decoded frame length indicates the number of samples in - // lower-band in this case, multiply by 2 to get the total number - // of samples. - *frameLength <<= 1; - } - + if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) { + /* The decoded frame length indicates the number of samples in + * lower-band in this case, multiply by 2 to get the total number + * of samples. */ + *frameLength <<= 1; + } return 0; } @@ -2141,10 +1781,10 @@ WebRtc_Word16 WebRtcIsac_ReadFrameLen( /******************************************************************************* * WebRtcIsac_GetNewFrameLen(...) * - * returns the frame lenght (in samples) of the next packet. In the case of - * channel-adaptive mode, iSAC decides on its frame lenght based on the - * estimated bottleneck this allows a user to prepare for the next packet - * (at the encoder). + * This function returns the frame length (in samples) of the next packet. + * In the case of channel-adaptive mode, iSAC decides on its frame length based + * on the estimated bottleneck, this AOI allows a user to prepare for the next + * packet (at the encoder). * * The primary usage is in CE to make the iSAC works in channel-adaptive mode * @@ -2154,23 +1794,15 @@ WebRtc_Word16 WebRtcIsac_ReadFrameLen( * Return Value : frame lenght in samples * */ -WebRtc_Word16 WebRtcIsac_GetNewFrameLen( - ISACStruct *ISAC_main_inst) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_GetNewFrameLen(ISACStruct* ISAC_main_inst) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - /* Return new frame length */ - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - return (instISAC->instLB.ISACencLB_obj.new_framelength); - } - else - { - return ((instISAC->instLB.ISACencLB_obj.new_framelength) << 1); - } + /* Return new frame length. */ + if (instISAC->encoderSamplingRateKHz == kIsacWideband) { + return (instISAC->instLB.ISACencLB_obj.new_framelength); + } else { + return ((instISAC->instLB.ISACencLB_obj.new_framelength) << 1); + } } @@ -2178,8 +1810,8 @@ WebRtc_Word16 WebRtcIsac_GetNewFrameLen( * WebRtcIsac_GetErrorCode(...) * * This function can be used to check the error code of an iSAC instance. - * When a function returns -1 a error code will be set for that instance. - * The function below extract the code of the last error that occured in + * When a function returns -1 an error code will be set for that instance. + * The function below extracts the code of the last error that occurred in * the specified instance. * * Input: @@ -2187,14 +1819,8 @@ WebRtc_Word16 WebRtcIsac_GetNewFrameLen( * * Return value : Error code */ -WebRtc_Word16 WebRtcIsac_GetErrorCode( - ISACStruct *ISAC_main_inst) -{ - ISACMainStruct *instISAC; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - - return (instISAC->errorCode); +WebRtc_Word16 WebRtcIsac_GetErrorCode(ISACStruct* ISAC_main_inst) { + return ((ISACMainStruct*)ISAC_main_inst)->errorCode; } @@ -2202,12 +1828,12 @@ WebRtc_Word16 WebRtcIsac_GetErrorCode( * WebRtcIsac_GetUplinkBw(...) * * This function outputs the target bottleneck of the codec. In - * channel-adaptive mode, the target bottleneck is specified through in-band - * signalling retreived by bandwidth estimator. + * channel-adaptive mode, the target bottleneck is specified through an in-band + * signalling retrieved by bandwidth estimator. * In channel-independent, also called instantaneous mode, the target * bottleneck is provided to the encoder by calling xxx_control(...) (if - * xxx_control is never called the default values is). - * Note that the output is the iSAC internal operating bottleneck whch might + * xxx_control is never called, the default values are used.). + * Note that the output is the iSAC internal operating bottleneck which might * differ slightly from the one provided through xxx_control(). * * Input: @@ -2219,35 +1845,24 @@ WebRtc_Word16 WebRtcIsac_GetErrorCode( * Return value : -1 if error happens * 0 bit-rates computed correctly. */ -WebRtc_Word16 WebRtcIsac_GetUplinkBw( - ISACStruct* ISAC_main_inst, - WebRtc_Word32* bottleneck) -{ - ISACMainStruct* instISAC = (ISACMainStruct *)ISAC_main_inst; +WebRtc_Word16 WebRtcIsac_GetUplinkBw(ISACStruct* ISAC_main_inst, + WebRtc_Word32* bottleneck) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - if(instISAC->codingMode == 0) - { - // we are in adaptive mode then get the bottleneck from BWE - *bottleneck = (WebRtc_Word32)instISAC->bwestimator_obj.send_bw_avg; - } - else - { - *bottleneck = instISAC->bottleneck; - } - - if((*bottleneck > 32000) && (*bottleneck < 38000)) - { - *bottleneck = 32000; - } - else if((*bottleneck > 45000) && (*bottleneck < 50000)) - { - *bottleneck = 45000; - } - else if(*bottleneck > 56000) - { - *bottleneck = 56000; - } + if (instISAC->codingMode == 0) { + /* We are in adaptive mode then get the bottleneck from BWE. */ + *bottleneck = (WebRtc_Word32)instISAC->bwestimator_obj.send_bw_avg; + } else { + *bottleneck = instISAC->bottleneck; + } + if ((*bottleneck > 32000) && (*bottleneck < 38000)) { + *bottleneck = 32000; + } else if ((*bottleneck > 45000) && (*bottleneck < 50000)) { + *bottleneck = 45000; + } else if (*bottleneck > 56000) { + *bottleneck = 56000; + } return 0; } @@ -2283,61 +1898,48 @@ WebRtc_Word16 WebRtcIsac_GetUplinkBw( * Return value : 0 if successful * -1 if error happens */ -WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize( - ISACStruct* ISAC_main_inst, - WebRtc_Word16 maxPayloadBytes) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize(ISACStruct* ISAC_main_inst, + WebRtc_Word16 maxPayloadBytes) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; WebRtc_Word16 status = 0; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; + /* Check if encoder initiated */ + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; + if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { + /* Sanity check. */ + if (maxPayloadBytes < 120) { + /* 'maxRate' is out of valid range + * set to the acceptable value and return -1. */ + maxPayloadBytes = 120; + status = -1; } - if(instISAC->encoderSamplingRateKHz == kIsacSuperWideband) - { - // sanity check - if(maxPayloadBytes < 120) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = 120; - status = -1; - } - - /* sanity check */ - if(maxPayloadBytes > STREAM_SIZE_MAX) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = STREAM_SIZE_MAX; - status = -1; - } + /* sanity check */ + if (maxPayloadBytes > STREAM_SIZE_MAX) { + /* maxRate is out of valid range, + * set to the acceptable value and return -1. */ + maxPayloadBytes = STREAM_SIZE_MAX; + status = -1; } - else - { - if(maxPayloadBytes < 120) - { - // max payload-size is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = 120; - status = -1; - } - if(maxPayloadBytes > STREAM_SIZE_MAX_60) - { - // max payload-size is out of valid range - // set to the acceptable value and return -1. - maxPayloadBytes = STREAM_SIZE_MAX_60; - status = -1; - } + } else { + if (maxPayloadBytes < 120) { + /* Max payload-size is out of valid range + * set to the acceptable value and return -1. */ + maxPayloadBytes = 120; + status = -1; } + if (maxPayloadBytes > STREAM_SIZE_MAX_60) { + /* Max payload-size is out of valid range + * set to the acceptable value and return -1. */ + maxPayloadBytes = STREAM_SIZE_MAX_60; + status = -1; + } + } instISAC->maxPayloadSizeBytes = maxPayloadBytes; UpdatePayloadSizeLimit(instISAC); return status; @@ -2379,68 +1981,52 @@ WebRtc_Word16 WebRtcIsac_SetMaxPayloadSize( * Return value : 0 if successful * -1 if error happens */ -WebRtc_Word16 WebRtcIsac_SetMaxRate( - ISACStruct* ISAC_main_inst, - WebRtc_Word32 maxRate) -{ - ISACMainStruct *instISAC; +WebRtc_Word16 WebRtcIsac_SetMaxRate(ISACStruct* ISAC_main_inst, + WebRtc_Word32 maxRate) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; WebRtc_Word16 maxRateInBytesPer30Ms; WebRtc_Word16 status = 0; - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct *)ISAC_main_inst; - /* check if encoder initiated */ - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - return -1; - } - /* - Calculate maximum number of bytes per 30 msec packets for the - given maximum rate. Multiply with 30/1000 to get number of - bits per 30 ms, divide by 8 to get number of bytes per 30 ms: - maxRateInBytes = floor((maxRate * 30/1000) / 8); - */ - maxRateInBytesPer30Ms = (WebRtc_Word16)(maxRate*3/800); + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + return -1; + } + /* Calculate maximum number of bytes per 30 msec packets for the + given maximum rate. Multiply with 30/1000 to get number of + bits per 30 ms, divide by 8 to get number of bytes per 30 ms: + maxRateInBytes = floor((maxRate * 30/1000) / 8); */ + maxRateInBytesPer30Ms = (WebRtc_Word16)(maxRate * 3 / 800); - if(instISAC->encoderSamplingRateKHz == kIsacWideband) - { - if(maxRate < 32000) - { - // max rate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = 120; - status = -1; - } - - if(maxRate > 53400) - { - // max rate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = 200; - status = -1; - } + if (instISAC->encoderSamplingRateKHz == kIsacWideband) { + if (maxRate < 32000) { + /* 'maxRate' is out of valid range. + * Set to the acceptable value and return -1. */ + maxRateInBytesPer30Ms = 120; + status = -1; } - else - { - if(maxRateInBytesPer30Ms < 120) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = 120; - status = -1; - } - if(maxRateInBytesPer30Ms > STREAM_SIZE_MAX) - { - // maxRate is out of valid range - // set to the acceptable value and return -1. - maxRateInBytesPer30Ms = STREAM_SIZE_MAX; - status = -1; - } + if (maxRate > 53400) { + /* 'maxRate' is out of valid range. + * Set to the acceptable value and return -1. */ + maxRateInBytesPer30Ms = 200; + status = -1; } + } else { + if (maxRateInBytesPer30Ms < 120) { + /* 'maxRate' is out of valid range + * Sset to the acceptable value and return -1. */ + maxRateInBytesPer30Ms = 120; + status = -1; + } + + if (maxRateInBytesPer30Ms > STREAM_SIZE_MAX) { + /* 'maxRate' is out of valid range. + * Set to the acceptable value and return -1. */ + maxRateInBytesPer30Ms = STREAM_SIZE_MAX; + status = -1; + } + } instISAC->maxRateBytesPer30Ms = maxRateInBytesPer30Ms; UpdatePayloadSizeLimit(instISAC); return status; @@ -2450,8 +2036,8 @@ WebRtc_Word16 WebRtcIsac_SetMaxRate( /**************************************************************************** * WebRtcIsac_GetRedPayload(...) * - * Populates "encoded" with the redundant payload of the recently encoded - * frame. This function has to be called once that WebRtcIsac_Encode(...) + * This function populates "encoded" with the redundant payload of the recently + * encodedframe. This function has to be called once that WebRtcIsac_Encode(...) * returns a positive value. Regardless of the frame-size this function will * be called only once after encoding is completed. The bit-stream is * targeted for 16000 bit/sec. @@ -2465,106 +2051,82 @@ WebRtc_Word16 WebRtcIsac_SetMaxRate( * * Return value : >0 - Length (in bytes) of coded data * : -1 - Error - * - * */ -WebRtc_Word16 WebRtcIsac_GetRedPayload( - ISACStruct* ISAC_main_inst, - WebRtc_Word16* encoded) -{ - ISACMainStruct* instISAC; - Bitstr iSACBitStreamInst; - WebRtc_Word16 streamLenLB; - WebRtc_Word16 streamLenUB; - WebRtc_Word16 streamLen; - WebRtc_Word16 totalLenUB; - WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; +WebRtc_Word16 WebRtcIsac_GetRedPayload(ISACStruct* ISAC_main_inst, + WebRtc_Word16* encoded) { + Bitstr iSACBitStreamInst; + WebRtc_Word16 streamLenLB; + WebRtc_Word16 streamLenUB; + WebRtc_Word16 streamLen; + WebRtc_Word16 totalLenUB; + WebRtc_UWord8* ptrEncodedUW8 = (WebRtc_UWord8*)encoded; + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; #ifndef WEBRTC_BIG_ENDIAN int k; #endif - /* typecast pointer to real structure */ - instISAC = (ISACMainStruct*)ISAC_main_inst; - - - if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; - } - - - iSACBitStreamInst.W_upper = 0xFFFFFFFF; - iSACBitStreamInst.streamval = 0; - iSACBitStreamInst.stream_index = 0; + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; + } + WebRtcIsac_ResetBitstream(&(iSACBitStreamInst)); streamLenLB = WebRtcIsac_EncodeStoredDataLb( - &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, - &iSACBitStreamInst, - instISAC->instLB.ISACencLB_obj.lastBWIdx, - RCU_TRANSCODING_SCALE); + &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, + &iSACBitStreamInst, + instISAC->instLB.ISACencLB_obj.lastBWIdx, + RCU_TRANSCODING_SCALE); + if (streamLenLB < 0) { + return -1; + } - if(streamLenLB < 0) - { - return -1; - } - - /* convert from bytes to WebRtc_Word16 */ + /* convert from bytes to WebRtc_Word16. */ memcpy(ptrEncodedUW8, iSACBitStreamInst.stream, streamLenLB); - streamLen = streamLenLB; - - if(instISAC->bandwidthKHz == isac8kHz) - { - return streamLenLB; - } + if (instISAC->bandwidthKHz == isac8kHz) { + return streamLenLB; + } streamLenUB = WebRtcIsac_GetRedPayloadUb( - &instISAC->instUB.ISACencUB_obj.SaveEnc_obj, - &iSACBitStreamInst, instISAC->bandwidthKHz); + &instISAC->instUB.ISACencUB_obj.SaveEnc_obj, + &iSACBitStreamInst, instISAC->bandwidthKHz); + if (streamLenUB < 0) { + /* An error has happened but this is not the error due to a + * bit-stream larger than the limit. */ + return -1; + } - if(streamLenUB < 0) - { - // an error has happened but this is not the error due to a - // bit-stream larger than the limit - return -1; - } - - // We have one byte to write the total length of the upper band - // the length include the bitstream length, check-sum and the - // single byte where the length is written to. This is according to - // iSAC wideband and how the "garbage" is dealt. + /* We have one byte to write the total length of the upper-band. + * The length includes the bit-stream length, check-sum and the + * single byte where the length is written to. This is according to + * iSAC wideband and how the "garbage" is dealt. */ totalLenUB = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; - if(totalLenUB > 255) - { - streamLenUB = 0; - } + if (totalLenUB > 255) { + streamLenUB = 0; + } - // Generate CRC if required. - if((instISAC->bandwidthKHz != isac8kHz) && - (streamLenUB > 0)) - { - WebRtc_UWord32 crc; - streamLen += totalLenUB; - ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)totalLenUB; - memcpy(&ptrEncodedUW8[streamLenLB+1], iSACBitStreamInst.stream, streamLenUB); + /* Generate CRC if required. */ + if ((instISAC->bandwidthKHz != isac8kHz) && + (streamLenUB > 0)) { + WebRtc_UWord32 crc; + streamLen += totalLenUB; + ptrEncodedUW8[streamLenLB] = (WebRtc_UWord8)totalLenUB; + memcpy(&ptrEncodedUW8[streamLenLB + 1], iSACBitStreamInst.stream, + streamLenUB); - WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), - streamLenUB, &crc); + WebRtcIsac_GetCrc((WebRtc_Word16*)(&(ptrEncodedUW8[streamLenLB + 1])), + streamLenUB, &crc); #ifndef WEBRTC_BIG_ENDIAN - for(k = 0; k < LEN_CHECK_SUM_WORD8; k++) - { - ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = - (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); - } -#else - memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, - LEN_CHECK_SUM_WORD8); -#endif + for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { + ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = + (WebRtc_UWord8)((crc >> (24 - k * 8)) & 0xFF); } - - +#else + memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, + LEN_CHECK_SUM_WORD8); +#endif + } return streamLen; } @@ -2578,19 +2140,18 @@ WebRtc_Word16 WebRtcIsac_GetRedPayload( * - version : Pointer to character string * */ -void WebRtcIsac_version(char *version) -{ +void WebRtcIsac_version(char* version) { strcpy(version, "4.3.0"); } /****************************************************************************** * WebRtcIsac_SetEncSampRate() - * Set the sampling rate of the encoder. Initialization of the encoder WILL - * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz - * which is set when the instance is created. The encoding-mode and the - * bottleneck remain unchanged by this call, however, the maximum rate and - * maximum payload-size will reset to their default value. + * This function sets the sampling rate of the encoder. Initialization of the + * encoder WILL NOT overwrite the sampling rate of the encoder. The default + * value is 16 kHz which is set when the instance is created. The encoding-mode + * and the bottleneck remain unchanged by this call, however, the maximum rate + * and maximum payload-size will be reset to their default values. * * Input: * - ISAC_main_inst : iSAC instance @@ -2599,108 +2160,87 @@ void WebRtcIsac_version(char *version) * Return value : 0 if successful * -1 if failed. */ -WebRtc_Word16 WebRtcIsac_SetEncSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate) -{ - ISACMainStruct* instISAC; +WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, + enum IsacSamplingRate sampRate) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - instISAC = (ISACMainStruct*)ISAC_main_inst; - - if((sampRate != kIsacWideband) && - (sampRate != kIsacSuperWideband)) - { - // Sampling Frequency is not supported - instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; - return -1; + if ((sampRate != kIsacWideband) && + (sampRate != kIsacSuperWideband)) { + /* Sampling Frequency is not supported. */ + instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; + return -1; + } else if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + if (sampRate == kIsacWideband) { + instISAC->bandwidthKHz = isac8kHz; + } else { + instISAC->bandwidthKHz = isac16kHz; } - else if((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) - { - if(sampRate == kIsacWideband) - { - instISAC->bandwidthKHz = isac8kHz; + instISAC->encoderSamplingRateKHz = sampRate; + return 0; + } else { + ISACUBStruct* instUB = &(instISAC->instUB); + ISACLBStruct* instLB = &(instISAC->instLB); + double bottleneckLB; + double bottleneckUB; + WebRtc_Word32 bottleneck = instISAC->bottleneck; + WebRtc_Word16 codingMode = instISAC->codingMode; + WebRtc_Word16 frameSizeMs = instLB->ISACencLB_obj.new_framelength / + (FS / 1000); + + if ((sampRate == kIsacWideband) && + (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { + /* Changing from super-wideband to wideband. + * we don't need to re-initialize the encoder of the lower-band. */ + instISAC->bandwidthKHz = isac8kHz; + if (codingMode == 1) { + ControlLb(instLB, + (bottleneck > 32000) ? 32000 : bottleneck, FRAMESIZE); } - else - { - instISAC->bandwidthKHz = isac16kHz; + instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; + instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; + } else if ((sampRate == kIsacSuperWideband) && + (instISAC->encoderSamplingRateKHz == kIsacWideband)) { + if (codingMode == 1) { + WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB, + &(instISAC->bandwidthKHz)); + } + + instISAC->bandwidthKHz = isac16kHz; + instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; + instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; + + EncoderInitLb(instLB, codingMode, sampRate); + EncoderInitUb(instUB, instISAC->bandwidthKHz); + + memset(instISAC->analysisFBState1, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); + memset(instISAC->analysisFBState2, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); + + if (codingMode == 1) { + instISAC->bottleneck = bottleneck; + ControlLb(instLB, bottleneckLB, + (instISAC->bandwidthKHz == isac8kHz) ? frameSizeMs:FRAMESIZE); + if (instISAC->bandwidthKHz > isac8kHz) { + ControlUb(instUB, bottleneckUB); + } + } else { + instLB->ISACencLB_obj.enforceFrameSize = 0; + instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES; } - instISAC->encoderSamplingRateKHz = sampRate; - return 0; - } - else - { - ISACUBStruct* instUB = &(instISAC->instUB); - ISACLBStruct* instLB = &(instISAC->instLB); - double bottleneckLB; - double bottleneckUB; - WebRtc_Word32 bottleneck = instISAC->bottleneck; - WebRtc_Word16 codingMode = instISAC->codingMode; - WebRtc_Word16 frameSizeMs = instLB->ISACencLB_obj.new_framelength / (FS / 1000); - - if((sampRate == kIsacWideband) && - (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) - { - // changing from super-wideband to wideband. - // we don't need to re-initialize the encoder of the - // lower-band. - instISAC->bandwidthKHz = isac8kHz; - if(codingMode == 1) - { - ControlLb(instLB, - (bottleneck > 32000)? 32000:bottleneck, FRAMESIZE); - } - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; - } - else if((sampRate == kIsacSuperWideband) && - (instISAC->encoderSamplingRateKHz == kIsacWideband)) - { - if(codingMode == 1) - { - WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB, - &(instISAC->bandwidthKHz)); - } - - instISAC->bandwidthKHz = isac16kHz; - instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; - instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; - - EncoderInitLb(instLB, codingMode, sampRate); - EncoderInitUb(instUB, instISAC->bandwidthKHz); - - memset(instISAC->analysisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->analysisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - if(codingMode == 1) - { - instISAC->bottleneck = bottleneck; - ControlLb(instLB, bottleneckLB, - (instISAC->bandwidthKHz == isac8kHz)? frameSizeMs:FRAMESIZE); - if(instISAC->bandwidthKHz > isac8kHz) - { - ControlUb(instUB, bottleneckUB); - } - } - else - { - instLB->ISACencLB_obj.enforceFrameSize = 0; - instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES; - } - } - instISAC->encoderSamplingRateKHz = sampRate; - return 0; } + instISAC->encoderSamplingRateKHz = sampRate; + return 0; + } } /****************************************************************************** * WebRtcIsac_SetDecSampRate() - * Set the sampling rate of the decoder. Initialization of the decoder WILL - * NOT overwrite the sampling rate of the encoder. The default value is 16 kHz - * which is set when the instance is created. + * This function sets the sampling rate of the decoder. Initialization of the + * decoder WILL NOT overwrite the sampling rate of the encoder. The default + * value is 16 kHz which is set when the instance is created. * * Input: * - ISAC_main_inst : iSAC instance @@ -2709,42 +2249,32 @@ WebRtc_Word16 WebRtcIsac_SetEncSampRate( * Return value : 0 if successful * -1 if failed. */ -WebRtc_Word16 WebRtcIsac_SetDecSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate) -{ - ISACMainStruct* instISAC; +WebRtc_Word16 WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, + enum IsacSamplingRate sampRate) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - instISAC = (ISACMainStruct*)ISAC_main_inst; + if ((sampRate != kIsacWideband) && + (sampRate != kIsacSuperWideband)) { + /* Sampling Frequency is not supported. */ + instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; + return -1; + } else { + if ((instISAC->decoderSamplingRateKHz == kIsacWideband) && + (sampRate == kIsacSuperWideband)) { + /* Switching from wideband to super-wideband at the decoder + * we need to reset the filter-bank and initialize upper-band decoder. */ + memset(instISAC->synthesisFBState1, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); + memset(instISAC->synthesisFBState2, 0, + FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - if((sampRate != kIsacWideband) && - (sampRate != kIsacSuperWideband)) - { - // Sampling Frequency is not supported - instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; - return -1; - } - else - { - if((instISAC->decoderSamplingRateKHz == kIsacWideband) && - (sampRate == kIsacSuperWideband)) - { - // switching from wideband to super-wideband at the decoder - // we need to reset the filter-bank and initialize - // upper-band decoder. - memset(instISAC->synthesisFBState1, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - memset(instISAC->synthesisFBState2, 0, - FB_STATE_SIZE_WORD32 * sizeof(WebRtc_Word32)); - - if(DecoderInitUb(&(instISAC->instUB)) < 0) - { - return -1; - } - } - instISAC->decoderSamplingRateKHz = sampRate; - return 0; + if (DecoderInitUb(&(instISAC->instUB)) < 0) { + return -1; + } } + instISAC->decoderSamplingRateKHz = sampRate; + return 0; + } } @@ -2759,13 +2289,8 @@ WebRtc_Word16 WebRtcIsac_SetDecSampRate( * is expected to be sampled at this rate. * */ -enum IsacSamplingRate WebRtcIsac_EncSampRate( - ISACStruct* ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - +enum IsacSamplingRate WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; return instISAC->encoderSamplingRateKHz; } @@ -2782,12 +2307,7 @@ enum IsacSamplingRate WebRtcIsac_EncSampRate( * sampling rate of the decoded audio. * */ -enum IsacSamplingRate WebRtcIsac_DecSampRate( - ISACStruct* ISAC_main_inst) -{ - ISACMainStruct* instISAC; - - instISAC = (ISACMainStruct*)ISAC_main_inst; - +enum IsacSamplingRate WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) { + ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; return instISAC->decoderSamplingRateKHz; } diff --git a/src/modules/audio_coding/codecs/iSAC/main/source/settings.h b/src/modules/audio_coding/codecs/iSAC/main/source/settings.h index 600d8aa989..9c1ec1e6a0 100644 --- a/src/modules/audio_coding/codecs/iSAC/main/source/settings.h +++ b/src/modules/audio_coding/codecs/iSAC/main/source/settings.h @@ -81,7 +81,7 @@ #define UB16_INTERPOL_SEGMENTS 3 #define LB_TOTAL_DELAY_SAMPLES 48 enum ISACBandwidth {isac8kHz = 8, isac12kHz = 12, isac16kHz = 16}; -enum ISACBand{isacLowerBand = 0, isacUpperBand = 1}; +enum ISACBand {kIsacLowerBand = 0, kIsacUpperBand12 = 1, kIsacUpperBand16 = 2}; #define UB_LPC_GAIN_DIM SUBFRAMES #define FB_STATE_SIZE_WORD32 6