/* * Copyright (c) 2011 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 * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ /* * decode_B.c * * This file contains definition of funtions for decoding. * Decoding of lower-band, including normal-decoding and RCU decoding. * Decoding of upper-band, including 8-12 kHz, when the bandwidth is * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz. * */ #include "codec.h" #include "entropy_coding.h" #include "pitch_estimator.h" #include "bandwidth_estimator.h" #include "structs.h" #include "settings.h" #include #include #include /* * 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 k, model; int len, err; WebRtc_Word16 bandwidthInd; float LP_dec_float[FRAMESAMPLES_HALF]; float HP_dec_float[FRAMESAMPLES_HALF]; double LPw[FRAMESAMPLES_HALF]; double HPw[FRAMESAMPLES_HALF]; double LPw_pf[FRAMESAMPLES_HALF]; double lo_filt_coef[(ORDERLO+1)*SUBFRAMES]; double hi_filt_coef[(ORDERHI+1)*SUBFRAMES]; double real_f[FRAMESAMPLES_HALF]; double imag_f[FRAMESAMPLES_HALF]; double PitchLags[4]; double PitchGains[4]; double AvgPitchGain; WebRtc_Word16 PitchGains_Q12[4]; WebRtc_Word16 AvgPitchGain_Q12; float gain; int frame_nb; /* counter */ int frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */ int processed_samples; (ISACdecLB_obj->bitstr_obj).W_upper = 0xFFFFFFFF; (ISACdecLB_obj->bitstr_obj).streamval = 0; (ISACdecLB_obj->bitstr_obj).stream_index = 0; len = 0; /* 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 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); err = WebRtcIsac_DecodeSendBW(&ISACdecLB_obj->bitstr_obj, &bandwidthInd); if (err < 0) { // error check return err; } /* 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), PitchGains_Q12); if (err < 0) { // error check return err; } err = WebRtcIsac_DecodePitchLag(&ISACdecLB_obj->bitstr_obj, PitchGains_Q12, PitchLags); if (err < 0) { // error check return err; } AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3])>>2; /* decode & dequantize FiltCoef */ err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, lo_filt_coef,hi_filt_coef, &model); if (err < 0) { // error check return err; } /* decode & dequantize spectrum */ len = WebRtcIsac_DecodeSpecLb(&ISACdecLB_obj->bitstr_obj, real_f, imag_f, AvgPitchGain_Q12); if (len < 0) { // error check return len; } /* inverse transform */ WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecLB_obj->fftstr_obj); /* convert PitchGains back to FLOAT for pitchfilter_post */ for (k = 0; k < 4; k++) { PitchGains[k] = ((float)PitchGains_Q12[k])/4096; } 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; 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; } if(isRCUPayload) { for (k = 0; k < FRAMESAMPLES_HALF; k++) { /* compensation for transcoding gain changes*/ LPw_pf[k] *= RCU_TRANSCODING_SCALE; HPw[k] *= RCU_TRANSCODING_SCALE; } } /* 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, LP_dec_float); WebRtcIsac_NormLatticeFilterAr(ORDERHI, ISACdecLB_obj->maskfiltstr_obj.PostStateHiF, (ISACdecLB_obj->maskfiltstr_obj).PostStateHiG, HPw, hi_filt_coef, HP_dec_float); /* recombine the 2 bands */ WebRtcIsac_FilterAndCombineFloat( LP_dec_float, HP_dec_float, signal_out + frame_nb * processed_samples, &ISACdecLB_obj->postfiltbankstr_obj); } return len; } /* * This decode function is called when the codec is operating in 16 kHz * bandwidth to decode the upperband, i.e. 8-16 kHz. * * 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 len, err; double halfFrameFirst[FRAMESAMPLES_HALF]; double halfFrameSecond[FRAMESAMPLES_HALF]; double percepFilterParam[(UB_LPC_ORDER+1) * (SUBFRAMES<<1) + (UB_LPC_ORDER+1)]; double real_f[FRAMESAMPLES_HALF]; double imag_f[FRAMESAMPLES_HALF]; len = 0; /* decode & dequantize FiltCoef */ memset(percepFilterParam, 0, sizeof(percepFilterParam)); err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, percepFilterParam, isac16kHz); if (err < 0) { // error check return err; } /* decode & dequantize spectrum */ len = WebRtcIsac_DecodeSpecUB16(&ISACdecUB_obj->bitstr_obj, real_f, imag_f); if (len < 0) { // error check return len; } if(isRCUPayload) { int 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 */ WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond, &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, halfFrameFirst, &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)], &signal_out[FRAMESAMPLES_HALF]); return len; } /* * This decode function is called when the codec operates at 0-12 kHz * bandwidth to decode the upperband, i.e. 8-12 kHz. * * At the encoder the upper-band is split into two band, 8-12 kHz & 12-16 * kHz, and only 8-12 kHz is encoded. At the decoder, 8-12 kHz band is * 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 len, err; float LP_dec_float[FRAMESAMPLES_HALF]; float HP_dec_float[FRAMESAMPLES_HALF]; double LPw[FRAMESAMPLES_HALF]; double HPw[FRAMESAMPLES_HALF]; double percepFilterParam[(UB_LPC_ORDER+1)*SUBFRAMES]; double real_f[FRAMESAMPLES_HALF]; double imag_f[FRAMESAMPLES_HALF]; len = 0; /* decode & dequantize FiltCoef */ err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, percepFilterParam, isac12kHz); if(err < 0) { // error check return err; } /* decode & dequantize spectrum */ len = WebRtcIsac_DecodeSpecUB12(&ISACdecUB_obj->bitstr_obj, real_f, imag_f); if(len < 0) { // error check return len; } if(isRCUPayload) { int 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 */ 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 */ memset(HP_dec_float, 0, sizeof(float) * (FRAMESAMPLES_HALF)); /* recombine the 2 bands */ WebRtcIsac_FilterAndCombineFloat(HP_dec_float, LP_dec_float, signal_out, &ISACdecUB_obj->postfiltbankstr_obj); return len; }