OLD | NEW |
| (Empty) |
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 | |
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 [o
rder] */ | |
54 const silk_float input[], /* I Input signal [l
ength] */ | |
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 (e
ven) */ | |
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 */ | |
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->Harm
Boost[ 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_le
ngth, 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 */ | |
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_MAS
K ] * HarmShapeFIR[ 0 ]; | |
185 n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MAS
K ] * HarmShapeFIR[ 1 ]; | |
186 n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MAS
K ] * 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 } | |
OLD | NEW |