1 /***********************************************************************
2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6 - Redistributions of source code must retain the above copyright notice,
7 this list of conditions and the following disclaimer.
8 - Redistributions in binary form must reproduce the above copyright
9 notice, this list of conditions and the following disclaimer in the
10 documentation and/or other materials provided with the distribution.
11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
12 names of specific contributors, may be used to endorse or promote
13 products derived from this software without specific prior written
14 permission.
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 POSSIBILITY OF SUCH DAMAGE.
26 ***********************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "main_FLP.h"
33 #include "tuning_parameters.h"
34
35 /*
36 * Prefilter for finding Quantizer input signal
37 */
38 static OPUS_INLINE void silk_prefilt_FLP(
39 silk_prefilter_state_FLP *P, /* I/O state */
40 silk_float st_res[], /* I */
41 silk_float xw[], /* O */
42 silk_float *HarmShapeFIR, /* I */
43 silk_float Tilt, /* I */
44 silk_float LF_MA_shp, /* I */
45 silk_float LF_AR_shp, /* I */
46 opus_int lag, /* I */
47 opus_int length /* I */
48 );
49
silk_warped_LPC_analysis_filter_FLP(silk_float state[],silk_float res[],const silk_float coef[],const silk_float input[],const silk_float lambda,const opus_int length,const opus_int order)50 static void silk_warped_LPC_analysis_filter_FLP(
51 silk_float state[], /* I/O State [order + 1] */
52 silk_float res[], /* O Residual signal [length] */
53 const silk_float coef[], /* I Coefficients [order] */
54 const silk_float input[], /* I Input signal [length] */
55 const silk_float lambda, /* I Warping factor */
56 const opus_int length, /* I Length of input signal */
57 const opus_int order /* I Filter order (even) */
58 )
59 {
60 opus_int n, i;
61 silk_float acc, tmp1, tmp2;
62
63 /* Order must be even */
64 silk_assert( ( order & 1 ) == 0 );
65
66 for( n = 0; n < length; n++ ) {
67 /* Output of lowpass section */
68 tmp2 = state[ 0 ] + lambda * state[ 1 ];
69 state[ 0 ] = input[ n ];
70 /* Output of allpass section */
71 tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );
72 state[ 1 ] = tmp2;
73 acc = coef[ 0 ] * tmp2;
74 /* Loop over allpass sections */
75 for( i = 2; i < order; i += 2 ) {
76 /* Output of allpass section */
77 tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );
78 state[ i ] = tmp1;
79 acc += coef[ i - 1 ] * tmp1;
80 /* Output of allpass section */
81 tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );
82 state[ i + 1 ] = tmp2;
83 acc += coef[ i ] * tmp2;
84 }
85 state[ order ] = tmp1;
86 acc += coef[ order - 1 ] * tmp1;
87 res[ n ] = input[ n ] - acc;
88 }
89 }
90
91 /*
92 * silk_prefilter. Main prefilter function
93 */
silk_prefilter_FLP(silk_encoder_state_FLP * psEnc,const silk_encoder_control_FLP * psEncCtrl,silk_float xw[],const silk_float x[])94 void silk_prefilter_FLP(
95 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
96 const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
97 silk_float xw[], /* O Weighted signal */
98 const silk_float x[] /* I Speech signal */
99 )
100 {
101 silk_prefilter_state_FLP *P = &psEnc->sPrefilt;
102 opus_int j, k, lag;
103 silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp;
104 silk_float B[ 2 ];
105 const silk_float *AR1_shp;
106 const silk_float *px;
107 silk_float *pxw;
108 silk_float HarmShapeFIR[ 3 ];
109 silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
110
111 /* Set up pointers */
112 px = x;
113 pxw = xw;
114 lag = P->lagPrev;
115 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
116 /* Update Variables that change per sub frame */
117 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
118 lag = psEncCtrl->pitchL[ k ];
119 }
120
121 /* Noise shape parameters */
122 HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] );
123 HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain;
124 HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain;
125 HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain;
126 Tilt = psEncCtrl->Tilt[ k ];
127 LF_MA_shp = psEncCtrl->LF_MA_shp[ k ];
128 LF_AR_shp = psEncCtrl->LF_AR_shp[ k ];
129 AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ];
130
131 /* Short term FIR filtering */
132 silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px,
133 (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
134
135 /* Reduce (mainly) low frequencies during harmonic emphasis */
136 B[ 0 ] = psEncCtrl->GainsPre[ k ];
137 B[ 1 ] = -psEncCtrl->GainsPre[ k ] *
138 ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT );
139 pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP;
140 for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
141 pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ];
142 }
143 P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
144
145 silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length );
146
147 px += psEnc->sCmn.subfr_length;
148 pxw += psEnc->sCmn.subfr_length;
149 }
150 P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
151 }
152
153 /*
154 * Prefilter for finding Quantizer input signal
155 */
silk_prefilt_FLP(silk_prefilter_state_FLP * P,silk_float st_res[],silk_float xw[],silk_float * HarmShapeFIR,silk_float Tilt,silk_float LF_MA_shp,silk_float LF_AR_shp,opus_int lag,opus_int length)156 static OPUS_INLINE void silk_prefilt_FLP(
157 silk_prefilter_state_FLP *P, /* I/O state */
158 silk_float st_res[], /* I */
159 silk_float xw[], /* O */
160 silk_float *HarmShapeFIR, /* I */
161 silk_float Tilt, /* I */
162 silk_float LF_MA_shp, /* I */
163 silk_float LF_AR_shp, /* I */
164 opus_int lag, /* I */
165 opus_int length /* I */
166 )
167 {
168 opus_int i;
169 opus_int idx, LTP_shp_buf_idx;
170 silk_float n_Tilt, n_LF, n_LTP;
171 silk_float sLF_AR_shp, sLF_MA_shp;
172 silk_float *LTP_shp_buf;
173
174 /* To speed up use temp variables instead of using the struct */
175 LTP_shp_buf = P->sLTP_shp;
176 LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
177 sLF_AR_shp = P->sLF_AR_shp;
178 sLF_MA_shp = P->sLF_MA_shp;
179
180 for( i = 0; i < length; i++ ) {
181 if( lag > 0 ) {
182 silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
183 idx = lag + LTP_shp_buf_idx;
184 n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];
185 n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ];
186 n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];
187 } else {
188 n_LTP = 0;
189 }
190
191 n_Tilt = sLF_AR_shp * Tilt;
192 n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;
193
194 sLF_AR_shp = st_res[ i ] - n_Tilt;
195 sLF_MA_shp = sLF_AR_shp - n_LF;
196
197 LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
198 LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;
199
200 xw[ i ] = sLF_MA_shp - n_LTP;
201 }
202 /* Copy temp variable back to state */
203 P->sLF_AR_shp = sLF_AR_shp;
204 P->sLF_MA_shp = sLF_MA_shp;
205 P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
206 }
207