/* Prefilter for finding Quantizer input signal */ static void silk_prefilt( SilkPrefilterState P, /* I/O state */ int[] st_res_Q12, /* I short term residual signal */ int[] xw_Q3, /* O prefiltered signal */ int xw_Q3_ptr, int HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ int Tilt_Q14, /* I Tilt shaping coeficient */ int LF_shp_Q14, /* I Low-frequancy shaping coeficients */ int lag, /* I Lag for harmonic shaping */ int length /* I Length of signals */ ) { int i, idx, LTP_shp_buf_idx; int n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; int sLF_MA_shp_Q12, sLF_AR_shp_Q12; short[] LTP_shp_buf; /* To speed up use temp variables instead of using the struct */ LTP_shp_buf = P.sLTP_shp; LTP_shp_buf_idx = P.sLTP_shp_buf_idx; sLF_AR_shp_Q12 = P.sLF_AR_shp_Q12; sLF_MA_shp_Q12 = P.sLF_MA_shp_Q12; for (i = 0; i < length; i++) { if (lag > 0) { /* unrolled loop */ Inlines.OpusAssert(SilkConstants.HARM_SHAPE_FIR_TAPS == 3); idx = lag + LTP_shp_buf_idx; n_LTP_Q12 = Inlines.silk_SMULBB(LTP_shp_buf[(idx - SilkConstants.HARM_SHAPE_FIR_TAPS / 2 - 1) & SilkConstants.LTP_MASK], HarmShapeFIRPacked_Q12); n_LTP_Q12 = Inlines.silk_SMLABT(n_LTP_Q12, LTP_shp_buf[(idx - SilkConstants.HARM_SHAPE_FIR_TAPS / 2) & SilkConstants.LTP_MASK], HarmShapeFIRPacked_Q12); n_LTP_Q12 = Inlines.silk_SMLABB(n_LTP_Q12, LTP_shp_buf[(idx - SilkConstants.HARM_SHAPE_FIR_TAPS / 2 + 1) & SilkConstants.LTP_MASK], HarmShapeFIRPacked_Q12); } else { n_LTP_Q12 = 0; } n_Tilt_Q10 = Inlines.silk_SMULWB(sLF_AR_shp_Q12, Tilt_Q14); n_LF_Q10 = Inlines.silk_SMLAWB(Inlines.silk_SMULWT(sLF_AR_shp_Q12, LF_shp_Q14), sLF_MA_shp_Q12, LF_shp_Q14); sLF_AR_shp_Q12 = Inlines.silk_SUB32(st_res_Q12[i], Inlines.silk_LSHIFT(n_Tilt_Q10, 2)); sLF_MA_shp_Q12 = Inlines.silk_SUB32(sLF_AR_shp_Q12, Inlines.silk_LSHIFT(n_LF_Q10, 2)); LTP_shp_buf_idx = (LTP_shp_buf_idx - 1) & SilkConstants.LTP_MASK; LTP_shp_buf[LTP_shp_buf_idx] = (short)Inlines.silk_SAT16(Inlines.silk_RSHIFT_ROUND(sLF_MA_shp_Q12, 12)); xw_Q3[xw_Q3_ptr + i] = Inlines.silk_RSHIFT_ROUND(Inlines.silk_SUB32(sLF_MA_shp_Q12, n_LTP_Q12), 9); } /* Copy temp variable back to state */ P.sLF_AR_shp_Q12 = sLF_AR_shp_Q12; P.sLF_MA_shp_Q12 = sLF_MA_shp_Q12; P.sLTP_shp_buf_idx = LTP_shp_buf_idx; }
internal static void silk_prefilter( SilkChannelEncoder psEnc, /* I/O Encoder state */ SilkEncoderControl psEncCtrl, /* I Encoder control */ int[] xw_Q3, /* O Weighted signal */ short[] x, /* I Speech signal */ int x_ptr ) { SilkPrefilterState P = psEnc.sPrefilt; int j, k, lag; int tmp_32; int AR1_shp_Q13; int px; int pxw_Q3; int HarmShapeGain_Q12, Tilt_Q14; int HarmShapeFIRPacked_Q12, LF_shp_Q14; int[] x_filt_Q12; int[] st_res_Q2; short[] B_Q10 = new short[2]; /* Set up pointers */ px = x_ptr; pxw_Q3 = 0; lag = P.lagPrev; x_filt_Q12 = new int[psEnc.subfr_length]; st_res_Q2 = new int[psEnc.subfr_length]; for (k = 0; k < psEnc.nb_subfr; k++) { /* Update Variables that change per sub frame */ if (psEnc.indices.signalType == SilkConstants.TYPE_VOICED) { lag = psEncCtrl.pitchL[k]; } /* Noise shape parameters */ HarmShapeGain_Q12 = Inlines.silk_SMULWB((int)psEncCtrl.HarmShapeGain_Q14[k], 16384 - psEncCtrl.HarmBoost_Q14[k]); Inlines.OpusAssert(HarmShapeGain_Q12 >= 0); HarmShapeFIRPacked_Q12 = Inlines.silk_RSHIFT(HarmShapeGain_Q12, 2); HarmShapeFIRPacked_Q12 |= Inlines.silk_LSHIFT((int)Inlines.silk_RSHIFT(HarmShapeGain_Q12, 1), 16); Tilt_Q14 = psEncCtrl.Tilt_Q14[k]; LF_shp_Q14 = psEncCtrl.LF_shp_Q14[k]; AR1_shp_Q13 = k * SilkConstants.MAX_SHAPE_LPC_ORDER; /* Short term FIR filtering*/ silk_warped_LPC_analysis_filter(P.sAR_shp, st_res_Q2, psEncCtrl.AR1_Q13, AR1_shp_Q13, x, px, (short)(psEnc.warping_Q16), psEnc.subfr_length, psEnc.shapingLPCOrder); /* Reduce (mainly) low frequencies during harmonic emphasis */ B_Q10[0] = (short)(Inlines.silk_RSHIFT_ROUND(psEncCtrl.GainsPre_Q14[k], 4)); tmp_32 = Inlines.silk_SMLABB(((int)((TuningParameters.INPUT_TILT) * ((long)1 << (26)) + 0.5)) /*Inlines.SILK_CONST(TuningParameters.INPUT_TILT, 26)*/, psEncCtrl.HarmBoost_Q14[k], HarmShapeGain_Q12); /* Q26 */ tmp_32 = Inlines.silk_SMLABB(tmp_32, psEncCtrl.coding_quality_Q14, ((int)((TuningParameters.HIGH_RATE_INPUT_TILT) * ((long)1 << (12)) + 0.5)) /*Inlines.SILK_CONST(TuningParameters.HIGH_RATE_INPUT_TILT, 12)*/); /* Q26 */ tmp_32 = Inlines.silk_SMULWB(tmp_32, -psEncCtrl.GainsPre_Q14[k]); /* Q24 */ tmp_32 = Inlines.silk_RSHIFT_ROUND(tmp_32, 14); /* Q10 */ B_Q10[1] = (short)(Inlines.silk_SAT16(tmp_32)); x_filt_Q12[0] = Inlines.silk_MLA(Inlines.silk_MUL(st_res_Q2[0], B_Q10[0]), P.sHarmHP_Q2, B_Q10[1]); for (j = 1; j < psEnc.subfr_length; j++) { x_filt_Q12[j] = Inlines.silk_MLA(Inlines.silk_MUL(st_res_Q2[j], B_Q10[0]), st_res_Q2[j - 1], B_Q10[1]); } P.sHarmHP_Q2 = st_res_Q2[psEnc.subfr_length - 1]; silk_prefilt(P, x_filt_Q12, xw_Q3, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc.subfr_length); px += psEnc.subfr_length; pxw_Q3 += psEnc.subfr_length; } P.lagPrev = psEncCtrl.pitchL[psEnc.nb_subfr - 1]; }