diff options
Diffstat (limited to 'webrtc/modules/audio_coding/codecs/isac/main/source/decode.c')
-rw-r--r-- | webrtc/modules/audio_coding/codecs/isac/main/source/decode.c | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/decode.c b/webrtc/modules/audio_coding/codecs/isac/main/source/decode.c new file mode 100644 index 0000000..e925efb --- /dev/null +++ b/webrtc/modules/audio_coding/codecs/isac/main/source/decode.c @@ -0,0 +1,304 @@ +/* + * 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 + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + + +/* + * function to decode the bitstream + * returns the total number of bytes in the stream + */ +int WebRtcIsac_DecodeLb(const TransformTables* transform_tables, + float* signal_out, ISACLBDecStruct* ISACdecLB_obj, + int16_t* current_framesamples, + int16_t isRCUPayload) { + int k; + int len, err; + int16_t 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; + int16_t PitchGains_Q12[4]; + int16_t AvgPitchGain_Q12; + + float gain; + + int frame_nb; /* counter */ + int frame_mode; /* 0 30ms, 1 for 60ms */ + /* Processed_samples: 480 (30, 60 ms). Cannot take other values. */ + + WebRtcIsac_ResetBitstream(&(ISACdecLB_obj->bitstr_obj)); + + 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) { + return err; + } + + /* 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) { + 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 & de-quantize pitch parameters */ + err = WebRtcIsac_DecodePitchGain(&ISACdecLB_obj->bitstr_obj, + PitchGains_Q12); + if (err < 0) { + return err; + } + + 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; + + /* Decode & de-quantize filter coefficients. */ + err = WebRtcIsac_DecodeLpc(&ISACdecLB_obj->bitstr_obj, lo_filt_coef, + hi_filt_coef); + if (err < 0) { + return err; + } + /* 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. */ + WebRtcIsac_Spec2time(transform_tables, 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 * FRAMESAMPLES, + &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(const TransformTables* transform_tables, + float* signal_out, ISACUBDecStruct* ISACdecUB_obj, + int16_t 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]; + const int16_t kAveragePitchGain = 0; /* No pitch-gain for upper-band. */ + len = 0; + + /* Decode & de-quantize filter coefficients. */ + memset(percepFilterParam, 0, sizeof(percepFilterParam)); + err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, + percepFilterParam, isac16kHz); + if (err < 0) { + return err; + } + + /* Decode & de-quantize spectrum. */ + len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain, + kIsacUpperBand16, real_f, imag_f); + if (len < 0) { + 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(transform_tables, + 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(const TransformTables* transform_tables, + float* signal_out, ISACUBDecStruct* ISACdecUB_obj, + int16_t 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]; + const int16_t kAveragePitchGain = 0; /* No pitch-gain for upper-band. */ + len = 0; + + /* Decode & dequantize filter coefficients. */ + err = WebRtcIsac_DecodeInterpolLpcUb(&ISACdecUB_obj->bitstr_obj, + percepFilterParam, isac12kHz); + if (err < 0) { + return err; + } + + /* Decode & de-quantize spectrum. */ + len = WebRtcIsac_DecodeSpec(&ISACdecUB_obj->bitstr_obj, kAveragePitchGain, + kIsacUpperBand12, real_f, imag_f); + if (len < 0) { + 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(transform_tables, + 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); + /* Zero for 12-16 kHz. */ + 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; +} |