/src/speex/libspeex/ltp.c
Line | Count | Source |
1 | | /* Copyright (C) 2002-2006 Jean-Marc Valin |
2 | | File: ltp.c |
3 | | Long-Term Prediction functions |
4 | | |
5 | | Redistribution and use in source and binary forms, with or without |
6 | | modification, are permitted provided that the following conditions |
7 | | are met: |
8 | | |
9 | | - Redistributions of source code must retain the above copyright |
10 | | notice, this list of conditions and the following disclaimer. |
11 | | |
12 | | - Redistributions in binary form must reproduce the above copyright |
13 | | notice, this list of conditions and the following disclaimer in the |
14 | | documentation and/or other materials provided with the distribution. |
15 | | |
16 | | - Neither the name of the Xiph.org Foundation nor the names of its |
17 | | contributors may be used to endorse or promote products derived from |
18 | | this software without specific prior written permission. |
19 | | |
20 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
24 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | | */ |
32 | | |
33 | | #ifdef HAVE_CONFIG_H |
34 | | #include "config.h" |
35 | | #endif |
36 | | |
37 | | #include <math.h> |
38 | | #include "ltp.h" |
39 | | #include "stack_alloc.h" |
40 | | #include "filters.h" |
41 | | #include "math_approx.h" |
42 | | #include "os_support.h" |
43 | | |
44 | | #ifndef NULL |
45 | | #define NULL 0 |
46 | | #endif |
47 | | |
48 | | |
49 | | #ifdef _USE_SSE |
50 | | #include "ltp_sse.h" |
51 | | #elif defined (ARM4_ASM) || defined(ARM5E_ASM) |
52 | | #include "ltp_arm4.h" |
53 | | #elif defined (BFIN_ASM) |
54 | | #include "ltp_bfin.h" |
55 | | #endif |
56 | | |
57 | | #ifndef OVERRIDE_INNER_PROD |
58 | | spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len) |
59 | 6.18M | { |
60 | 6.18M | spx_word32_t sum=0; |
61 | 6.18M | len >>= 2; |
62 | 133M | while(len--) |
63 | 127M | { |
64 | 127M | spx_word32_t part=0; |
65 | 127M | part = MAC16_16(part,*x++,*y++); |
66 | 127M | part = MAC16_16(part,*x++,*y++); |
67 | 127M | part = MAC16_16(part,*x++,*y++); |
68 | 127M | part = MAC16_16(part,*x++,*y++); |
69 | | /* HINT: If you had a 40-bit accumulator, you could shift only at the end */ |
70 | 127M | sum = ADD32(sum,SHR32(part,6)); |
71 | 127M | } |
72 | 6.18M | return sum; |
73 | 6.18M | } |
74 | | #endif |
75 | | |
76 | | #ifndef DISABLE_ENCODER |
77 | | |
78 | | #ifndef OVERRIDE_PITCH_XCORR |
79 | | #if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */ |
80 | | static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) |
81 | | { |
82 | | int i,j; |
83 | | for (i=0;i<nb_pitch;i+=4) |
84 | | { |
85 | | /* Compute correlation*/ |
86 | | /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/ |
87 | | spx_word32_t sum1=0; |
88 | | spx_word32_t sum2=0; |
89 | | spx_word32_t sum3=0; |
90 | | spx_word32_t sum4=0; |
91 | | const spx_word16_t *y = _y+i; |
92 | | const spx_word16_t *x = _x; |
93 | | spx_word16_t y0, y1, y2, y3; |
94 | | /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/ |
95 | | y0=*y++; |
96 | | y1=*y++; |
97 | | y2=*y++; |
98 | | y3=*y++; |
99 | | for (j=0;j<len;j+=4) |
100 | | { |
101 | | spx_word32_t part1; |
102 | | spx_word32_t part2; |
103 | | spx_word32_t part3; |
104 | | spx_word32_t part4; |
105 | | part1 = MULT16_16(*x,y0); |
106 | | part2 = MULT16_16(*x,y1); |
107 | | part3 = MULT16_16(*x,y2); |
108 | | part4 = MULT16_16(*x,y3); |
109 | | x++; |
110 | | y0=*y++; |
111 | | part1 = MAC16_16(part1,*x,y1); |
112 | | part2 = MAC16_16(part2,*x,y2); |
113 | | part3 = MAC16_16(part3,*x,y3); |
114 | | part4 = MAC16_16(part4,*x,y0); |
115 | | x++; |
116 | | y1=*y++; |
117 | | part1 = MAC16_16(part1,*x,y2); |
118 | | part2 = MAC16_16(part2,*x,y3); |
119 | | part3 = MAC16_16(part3,*x,y0); |
120 | | part4 = MAC16_16(part4,*x,y1); |
121 | | x++; |
122 | | y2=*y++; |
123 | | part1 = MAC16_16(part1,*x,y3); |
124 | | part2 = MAC16_16(part2,*x,y0); |
125 | | part3 = MAC16_16(part3,*x,y1); |
126 | | part4 = MAC16_16(part4,*x,y2); |
127 | | x++; |
128 | | y3=*y++; |
129 | | |
130 | | sum1 = ADD32(sum1,SHR32(part1,6)); |
131 | | sum2 = ADD32(sum2,SHR32(part2,6)); |
132 | | sum3 = ADD32(sum3,SHR32(part3,6)); |
133 | | sum4 = ADD32(sum4,SHR32(part4,6)); |
134 | | } |
135 | | corr[nb_pitch-1-i]=sum1; |
136 | | corr[nb_pitch-2-i]=sum2; |
137 | | corr[nb_pitch-3-i]=sum3; |
138 | | corr[nb_pitch-4-i]=sum4; |
139 | | } |
140 | | |
141 | | } |
142 | | #else |
143 | | static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack) |
144 | 37.4k | { |
145 | 37.4k | int i; |
146 | 4.58M | for (i=0;i<nb_pitch;i++) |
147 | 4.54M | { |
148 | | /* Compute correlation*/ |
149 | 4.54M | corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len); |
150 | 4.54M | } |
151 | | |
152 | 37.4k | } |
153 | | #endif |
154 | | #endif |
155 | | |
156 | | #ifndef OVERRIDE_COMPUTE_PITCH_ERROR |
157 | | static inline spx_word32_t compute_pitch_error(spx_word16_t *C, spx_word16_t *g, spx_word16_t pitch_control) |
158 | 28.6M | { |
159 | 28.6M | spx_word32_t sum = 0; |
160 | 28.6M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); |
161 | 28.6M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); |
162 | 28.6M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); |
163 | 28.6M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); |
164 | 28.6M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); |
165 | 28.6M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); |
166 | 28.6M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); |
167 | 28.6M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); |
168 | 28.6M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); |
169 | 28.6M | return sum; |
170 | 28.6M | } ltp.c:compute_pitch_error Line | Count | Source | 158 | 14.3M | { | 159 | 14.3M | spx_word32_t sum = 0; | 160 | 14.3M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); | 161 | 14.3M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); | 162 | 14.3M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); | 163 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); | 164 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); | 165 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); | 166 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); | 167 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); | 168 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); | 169 | 14.3M | return sum; | 170 | 14.3M | } |
ltp.c:compute_pitch_error Line | Count | Source | 158 | 14.3M | { | 159 | 14.3M | spx_word32_t sum = 0; | 160 | 14.3M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); | 161 | 14.3M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); | 162 | 14.3M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); | 163 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); | 164 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); | 165 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); | 166 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); | 167 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); | 168 | 14.3M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); | 169 | 14.3M | return sum; | 170 | 14.3M | } |
|
171 | | #endif |
172 | | |
173 | | #ifndef OVERRIDE_OPEN_LOOP_NBEST_PITCH |
174 | | void open_loop_nbest_pitch(spx_word16_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack) |
175 | 53.4k | { |
176 | 53.4k | int i,j,k; |
177 | 53.4k | VARDECL(spx_word32_t *best_score); |
178 | 53.4k | VARDECL(spx_word32_t *best_ener); |
179 | 53.4k | spx_word32_t e0; |
180 | 53.4k | VARDECL(spx_word32_t *corr); |
181 | | #ifdef FIXED_POINT |
182 | | /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) |
183 | | arrays for (normalized) 16-bit values */ |
184 | | VARDECL(spx_word16_t *corr16); |
185 | | VARDECL(spx_word16_t *ener16); |
186 | | spx_word32_t *energy; |
187 | | int cshift=0, eshift=0; |
188 | | int scaledown = 0; |
189 | 37.4k | ALLOC(corr16, end-start+1, spx_word16_t); |
190 | 37.4k | ALLOC(ener16, end-start+1, spx_word16_t); |
191 | 37.4k | ALLOC(corr, end-start+1, spx_word32_t); |
192 | | energy = corr; |
193 | | #else |
194 | | /* In floating-point, we need to float arrays and no normalized copies */ |
195 | | VARDECL(spx_word32_t *energy); |
196 | | spx_word16_t *corr16; |
197 | | spx_word16_t *ener16; |
198 | 16.0k | ALLOC(energy, end-start+2, spx_word32_t); |
199 | 16.0k | ALLOC(corr, end-start+1, spx_word32_t); |
200 | | corr16 = corr; |
201 | | ener16 = energy; |
202 | | #endif |
203 | | |
204 | 53.4k | ALLOC(best_score, N, spx_word32_t); |
205 | 53.4k | ALLOC(best_ener, N, spx_word32_t); |
206 | 355k | for (i=0;i<N;i++) |
207 | 302k | { |
208 | 302k | best_score[i]=-1; |
209 | 302k | best_ener[i]=0; |
210 | 302k | pitch[i]=start; |
211 | 302k | } |
212 | | |
213 | | #ifdef FIXED_POINT |
214 | 6.83M | for (i=-end;i<len;i++) |
215 | 6.80M | { |
216 | 6.80M | if (ABS16(sw[i])>16383) |
217 | 11.1k | { |
218 | 11.1k | scaledown=1; |
219 | 11.1k | break; |
220 | 11.1k | } |
221 | 6.80M | } |
222 | | /* If the weighted input is close to saturation, then we scale it down */ |
223 | 37.4k | if (scaledown) |
224 | 11.1k | { |
225 | 2.57M | for (i=-end;i<len;i++) |
226 | 2.56M | { |
227 | 2.56M | sw[i]=SHR16(sw[i],1); |
228 | 2.56M | } |
229 | 11.1k | } |
230 | | #endif |
231 | 53.4k | energy[0]=inner_prod(sw-start, sw-start, len); |
232 | 53.4k | e0=inner_prod(sw, sw, len); |
233 | 6.47M | for (i=start;i<end;i++) |
234 | 6.42M | { |
235 | | /* Update energy for next pitch*/ |
236 | 6.42M | energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6)); |
237 | 6.42M | if (energy[i-start+1] < 0) |
238 | 7.03k | energy[i-start+1] = 0; |
239 | 6.42M | } |
240 | | |
241 | | #ifdef FIXED_POINT |
242 | | eshift = normalize16(energy, ener16, 32766, end-start+1); |
243 | | #endif |
244 | | |
245 | | /* In fixed-point, this actually overrites the energy array (aliased to corr) */ |
246 | 53.4k | pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); |
247 | | |
248 | | #ifdef FIXED_POINT |
249 | | /* Normalize to 180 so we can square it and it still fits in 16 bits */ |
250 | | cshift = normalize16(corr, corr16, 180, end-start+1); |
251 | | /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */ |
252 | 37.4k | if (scaledown) |
253 | 11.1k | { |
254 | 2.57M | for (i=-end;i<len;i++) |
255 | 2.56M | { |
256 | 2.56M | sw[i]=SHL16(sw[i],1); |
257 | 2.56M | } |
258 | 11.1k | } |
259 | | #endif |
260 | | |
261 | | /* Search for the best pitch prediction gain */ |
262 | 6.53M | for (i=start;i<=end;i++) |
263 | 6.47M | { |
264 | 6.47M | spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); |
265 | | /* Instead of dividing the tmp by the energy, we multiply on the other side */ |
266 | 6.47M | if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) |
267 | 1.05M | { |
268 | | /* We can safely put it last and then check */ |
269 | 1.05M | best_score[N-1]=tmp; |
270 | 1.05M | best_ener[N-1]=ener16[i-start]+1; |
271 | 1.05M | pitch[N-1]=i; |
272 | | /* Check if it comes in front of others */ |
273 | 3.25M | for (j=0;j<N-1;j++) |
274 | 3.09M | { |
275 | 3.09M | if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) |
276 | 894k | { |
277 | 4.38M | for (k=N-1;k>j;k--) |
278 | 3.49M | { |
279 | 3.49M | best_score[k]=best_score[k-1]; |
280 | 3.49M | best_ener[k]=best_ener[k-1]; |
281 | 3.49M | pitch[k]=pitch[k-1]; |
282 | 3.49M | } |
283 | 894k | best_score[j]=tmp; |
284 | 894k | best_ener[j]=ener16[i-start]+1; |
285 | 894k | pitch[j]=i; |
286 | 894k | break; |
287 | 894k | } |
288 | 3.09M | } |
289 | 1.05M | } |
290 | 6.47M | } |
291 | | |
292 | | /* Compute open-loop gain if necessary */ |
293 | 53.4k | if (gain) |
294 | 23.3k | { |
295 | 163k | for (j=0;j<N;j++) |
296 | 140k | { |
297 | 140k | spx_word16_t g; |
298 | 140k | i=pitch[j]; |
299 | 140k | g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6)); |
300 | | /* FIXME: g = max(g,corr/energy) */ |
301 | 140k | if (g<0) |
302 | 51.5k | g = 0; |
303 | 140k | gain[j]=g; |
304 | 140k | } |
305 | 23.3k | } |
306 | | |
307 | | |
308 | 53.4k | } Line | Count | Source | 175 | 16.0k | { | 176 | 16.0k | int i,j,k; | 177 | 16.0k | VARDECL(spx_word32_t *best_score); | 178 | 16.0k | VARDECL(spx_word32_t *best_ener); | 179 | 16.0k | spx_word32_t e0; | 180 | 16.0k | VARDECL(spx_word32_t *corr); | 181 | | #ifdef FIXED_POINT | 182 | | /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) | 183 | | arrays for (normalized) 16-bit values */ | 184 | | VARDECL(spx_word16_t *corr16); | 185 | | VARDECL(spx_word16_t *ener16); | 186 | | spx_word32_t *energy; | 187 | | int cshift=0, eshift=0; | 188 | | int scaledown = 0; | 189 | | ALLOC(corr16, end-start+1, spx_word16_t); | 190 | | ALLOC(ener16, end-start+1, spx_word16_t); | 191 | | ALLOC(corr, end-start+1, spx_word32_t); | 192 | | energy = corr; | 193 | | #else | 194 | | /* In floating-point, we need to float arrays and no normalized copies */ | 195 | 16.0k | VARDECL(spx_word32_t *energy); | 196 | 16.0k | spx_word16_t *corr16; | 197 | 16.0k | spx_word16_t *ener16; | 198 | 16.0k | ALLOC(energy, end-start+2, spx_word32_t); | 199 | 16.0k | ALLOC(corr, end-start+1, spx_word32_t); | 200 | 16.0k | corr16 = corr; | 201 | 16.0k | ener16 = energy; | 202 | 16.0k | #endif | 203 | | | 204 | 16.0k | ALLOC(best_score, N, spx_word32_t); | 205 | 16.0k | ALLOC(best_ener, N, spx_word32_t); | 206 | 109k | for (i=0;i<N;i++) | 207 | 93.7k | { | 208 | 93.7k | best_score[i]=-1; | 209 | 93.7k | best_ener[i]=0; | 210 | 93.7k | pitch[i]=start; | 211 | 93.7k | } | 212 | | | 213 | | #ifdef FIXED_POINT | 214 | | for (i=-end;i<len;i++) | 215 | | { | 216 | | if (ABS16(sw[i])>16383) | 217 | | { | 218 | | scaledown=1; | 219 | | break; | 220 | | } | 221 | | } | 222 | | /* If the weighted input is close to saturation, then we scale it down */ | 223 | | if (scaledown) | 224 | | { | 225 | | for (i=-end;i<len;i++) | 226 | | { | 227 | | sw[i]=SHR16(sw[i],1); | 228 | | } | 229 | | } | 230 | | #endif | 231 | 16.0k | energy[0]=inner_prod(sw-start, sw-start, len); | 232 | 16.0k | e0=inner_prod(sw, sw, len); | 233 | 1.93M | for (i=start;i<end;i++) | 234 | 1.91M | { | 235 | | /* Update energy for next pitch*/ | 236 | 1.91M | energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6)); | 237 | 1.91M | if (energy[i-start+1] < 0) | 238 | 7.03k | energy[i-start+1] = 0; | 239 | 1.91M | } | 240 | | | 241 | | #ifdef FIXED_POINT | 242 | | eshift = normalize16(energy, ener16, 32766, end-start+1); | 243 | | #endif | 244 | | | 245 | | /* In fixed-point, this actually overrites the energy array (aliased to corr) */ | 246 | 16.0k | pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); | 247 | | | 248 | | #ifdef FIXED_POINT | 249 | | /* Normalize to 180 so we can square it and it still fits in 16 bits */ | 250 | | cshift = normalize16(corr, corr16, 180, end-start+1); | 251 | | /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */ | 252 | | if (scaledown) | 253 | | { | 254 | | for (i=-end;i<len;i++) | 255 | | { | 256 | | sw[i]=SHL16(sw[i],1); | 257 | | } | 258 | | } | 259 | | #endif | 260 | | | 261 | | /* Search for the best pitch prediction gain */ | 262 | 1.94M | for (i=start;i<=end;i++) | 263 | 1.93M | { | 264 | 1.93M | spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); | 265 | | /* Instead of dividing the tmp by the energy, we multiply on the other side */ | 266 | 1.93M | if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) | 267 | 344k | { | 268 | | /* We can safely put it last and then check */ | 269 | 344k | best_score[N-1]=tmp; | 270 | 344k | best_ener[N-1]=ener16[i-start]+1; | 271 | 344k | pitch[N-1]=i; | 272 | | /* Check if it comes in front of others */ | 273 | 932k | for (j=0;j<N-1;j++) | 274 | 887k | { | 275 | 887k | if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) | 276 | 299k | { | 277 | 1.60M | for (k=N-1;k>j;k--) | 278 | 1.30M | { | 279 | 1.30M | best_score[k]=best_score[k-1]; | 280 | 1.30M | best_ener[k]=best_ener[k-1]; | 281 | 1.30M | pitch[k]=pitch[k-1]; | 282 | 1.30M | } | 283 | 299k | best_score[j]=tmp; | 284 | 299k | best_ener[j]=ener16[i-start]+1; | 285 | 299k | pitch[j]=i; | 286 | 299k | break; | 287 | 299k | } | 288 | 887k | } | 289 | 344k | } | 290 | 1.93M | } | 291 | | | 292 | | /* Compute open-loop gain if necessary */ | 293 | 16.0k | if (gain) | 294 | 7.54k | { | 295 | 52.8k | for (j=0;j<N;j++) | 296 | 45.2k | { | 297 | 45.2k | spx_word16_t g; | 298 | 45.2k | i=pitch[j]; | 299 | 45.2k | g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6)); | 300 | | /* FIXME: g = max(g,corr/energy) */ | 301 | 45.2k | if (g<0) | 302 | 13.3k | g = 0; | 303 | 45.2k | gain[j]=g; | 304 | 45.2k | } | 305 | 7.54k | } | 306 | | | 307 | | | 308 | 16.0k | } |
Line | Count | Source | 175 | 37.4k | { | 176 | 37.4k | int i,j,k; | 177 | 37.4k | VARDECL(spx_word32_t *best_score); | 178 | 37.4k | VARDECL(spx_word32_t *best_ener); | 179 | 37.4k | spx_word32_t e0; | 180 | 37.4k | VARDECL(spx_word32_t *corr); | 181 | 37.4k | #ifdef FIXED_POINT | 182 | | /* In fixed-point, we need only one (temporary) array of 32-bit values and two (corr16, ener16) | 183 | | arrays for (normalized) 16-bit values */ | 184 | 37.4k | VARDECL(spx_word16_t *corr16); | 185 | 37.4k | VARDECL(spx_word16_t *ener16); | 186 | 37.4k | spx_word32_t *energy; | 187 | 37.4k | int cshift=0, eshift=0; | 188 | 37.4k | int scaledown = 0; | 189 | 37.4k | ALLOC(corr16, end-start+1, spx_word16_t); | 190 | 37.4k | ALLOC(ener16, end-start+1, spx_word16_t); | 191 | 37.4k | ALLOC(corr, end-start+1, spx_word32_t); | 192 | 37.4k | energy = corr; | 193 | | #else | 194 | | /* In floating-point, we need to float arrays and no normalized copies */ | 195 | | VARDECL(spx_word32_t *energy); | 196 | | spx_word16_t *corr16; | 197 | | spx_word16_t *ener16; | 198 | | ALLOC(energy, end-start+2, spx_word32_t); | 199 | | ALLOC(corr, end-start+1, spx_word32_t); | 200 | | corr16 = corr; | 201 | | ener16 = energy; | 202 | | #endif | 203 | | | 204 | 37.4k | ALLOC(best_score, N, spx_word32_t); | 205 | 37.4k | ALLOC(best_ener, N, spx_word32_t); | 206 | 246k | for (i=0;i<N;i++) | 207 | 208k | { | 208 | 208k | best_score[i]=-1; | 209 | 208k | best_ener[i]=0; | 210 | 208k | pitch[i]=start; | 211 | 208k | } | 212 | | | 213 | 37.4k | #ifdef FIXED_POINT | 214 | 6.83M | for (i=-end;i<len;i++) | 215 | 6.80M | { | 216 | 6.80M | if (ABS16(sw[i])>16383) | 217 | 11.1k | { | 218 | 11.1k | scaledown=1; | 219 | 11.1k | break; | 220 | 11.1k | } | 221 | 6.80M | } | 222 | | /* If the weighted input is close to saturation, then we scale it down */ | 223 | 37.4k | if (scaledown) | 224 | 11.1k | { | 225 | 2.57M | for (i=-end;i<len;i++) | 226 | 2.56M | { | 227 | 2.56M | sw[i]=SHR16(sw[i],1); | 228 | 2.56M | } | 229 | 11.1k | } | 230 | 37.4k | #endif | 231 | 37.4k | energy[0]=inner_prod(sw-start, sw-start, len); | 232 | 37.4k | e0=inner_prod(sw, sw, len); | 233 | 4.54M | for (i=start;i<end;i++) | 234 | 4.50M | { | 235 | | /* Update energy for next pitch*/ | 236 | 4.50M | energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(sw[-i-1],sw[-i-1]),6)), SHR32(MULT16_16(sw[-i+len-1],sw[-i+len-1]),6)); | 237 | 4.50M | if (energy[i-start+1] < 0) | 238 | 0 | energy[i-start+1] = 0; | 239 | 4.50M | } | 240 | | | 241 | 37.4k | #ifdef FIXED_POINT | 242 | 37.4k | eshift = normalize16(energy, ener16, 32766, end-start+1); | 243 | 37.4k | #endif | 244 | | | 245 | | /* In fixed-point, this actually overrites the energy array (aliased to corr) */ | 246 | 37.4k | pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); | 247 | | | 248 | 37.4k | #ifdef FIXED_POINT | 249 | | /* Normalize to 180 so we can square it and it still fits in 16 bits */ | 250 | 37.4k | cshift = normalize16(corr, corr16, 180, end-start+1); | 251 | | /* If we scaled weighted input down, we need to scale it up again (OK, so we've just lost the LSB, who cares?) */ | 252 | 37.4k | if (scaledown) | 253 | 11.1k | { | 254 | 2.57M | for (i=-end;i<len;i++) | 255 | 2.56M | { | 256 | 2.56M | sw[i]=SHL16(sw[i],1); | 257 | 2.56M | } | 258 | 11.1k | } | 259 | 37.4k | #endif | 260 | | | 261 | | /* Search for the best pitch prediction gain */ | 262 | 4.58M | for (i=start;i<=end;i++) | 263 | 4.54M | { | 264 | 4.54M | spx_word16_t tmp = MULT16_16_16(corr16[i-start],corr16[i-start]); | 265 | | /* Instead of dividing the tmp by the energy, we multiply on the other side */ | 266 | 4.54M | if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) | 267 | 707k | { | 268 | | /* We can safely put it last and then check */ | 269 | 707k | best_score[N-1]=tmp; | 270 | 707k | best_ener[N-1]=ener16[i-start]+1; | 271 | 707k | pitch[N-1]=i; | 272 | | /* Check if it comes in front of others */ | 273 | 2.32M | for (j=0;j<N-1;j++) | 274 | 2.21M | { | 275 | 2.21M | if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) | 276 | 594k | { | 277 | 2.78M | for (k=N-1;k>j;k--) | 278 | 2.18M | { | 279 | 2.18M | best_score[k]=best_score[k-1]; | 280 | 2.18M | best_ener[k]=best_ener[k-1]; | 281 | 2.18M | pitch[k]=pitch[k-1]; | 282 | 2.18M | } | 283 | 594k | best_score[j]=tmp; | 284 | 594k | best_ener[j]=ener16[i-start]+1; | 285 | 594k | pitch[j]=i; | 286 | 594k | break; | 287 | 594k | } | 288 | 2.21M | } | 289 | 707k | } | 290 | 4.54M | } | 291 | | | 292 | | /* Compute open-loop gain if necessary */ | 293 | 37.4k | if (gain) | 294 | 15.8k | { | 295 | 110k | for (j=0;j<N;j++) | 296 | 95.0k | { | 297 | 95.0k | spx_word16_t g; | 298 | 95.0k | i=pitch[j]; | 299 | 95.0k | g = DIV32(SHL32(EXTEND32(corr16[i-start]),cshift), 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(SHL32(EXTEND32(ener16[i-start]),eshift))),6)); | 300 | | /* FIXME: g = max(g,corr/energy) */ | 301 | 95.0k | if (g<0) | 302 | 38.2k | g = 0; | 303 | 95.0k | gain[j]=g; | 304 | 95.0k | } | 305 | 15.8k | } | 306 | | | 307 | | | 308 | 37.4k | } |
|
309 | | #endif |
310 | | |
311 | | #ifndef OVERRIDE_PITCH_GAIN_SEARCH_3TAP_VQ |
312 | | static int pitch_gain_search_3tap_vq( |
313 | | const signed char *gain_cdbk, |
314 | | int gain_cdbk_size, |
315 | | spx_word16_t *C16, |
316 | | spx_word16_t max_gain |
317 | | ) |
318 | 335k | { |
319 | 335k | const signed char *ptr=gain_cdbk; |
320 | 335k | int best_cdbk=0; |
321 | 335k | spx_word32_t best_sum=-VERY_LARGE32; |
322 | 335k | spx_word32_t sum=0; |
323 | 335k | spx_word16_t g[3]; |
324 | 335k | spx_word16_t pitch_control=64; |
325 | 335k | spx_word16_t gain_sum; |
326 | 335k | int i; |
327 | | |
328 | 29.0M | for (i=0;i<gain_cdbk_size;i++) { |
329 | | |
330 | 28.6M | ptr = gain_cdbk+4*i; |
331 | 28.6M | g[0]=ADD16((spx_word16_t)ptr[0],32); |
332 | 28.6M | g[1]=ADD16((spx_word16_t)ptr[1],32); |
333 | 28.6M | g[2]=ADD16((spx_word16_t)ptr[2],32); |
334 | 28.6M | gain_sum = (spx_word16_t)ptr[3]; |
335 | | |
336 | 28.6M | sum = compute_pitch_error(C16, g, pitch_control); |
337 | | |
338 | 28.6M | if (sum>best_sum && gain_sum<=max_gain) { |
339 | 1.05M | best_sum=sum; |
340 | 1.05M | best_cdbk=i; |
341 | 1.05M | } |
342 | 28.6M | } |
343 | | |
344 | 335k | return best_cdbk; |
345 | 335k | } ltp.c:pitch_gain_search_3tap_vq Line | Count | Source | 318 | 167k | { | 319 | 167k | const signed char *ptr=gain_cdbk; | 320 | 167k | int best_cdbk=0; | 321 | 167k | spx_word32_t best_sum=-VERY_LARGE32; | 322 | 167k | spx_word32_t sum=0; | 323 | 167k | spx_word16_t g[3]; | 324 | 167k | spx_word16_t pitch_control=64; | 325 | 167k | spx_word16_t gain_sum; | 326 | 167k | int i; | 327 | | | 328 | 14.5M | for (i=0;i<gain_cdbk_size;i++) { | 329 | | | 330 | 14.3M | ptr = gain_cdbk+4*i; | 331 | 14.3M | g[0]=ADD16((spx_word16_t)ptr[0],32); | 332 | 14.3M | g[1]=ADD16((spx_word16_t)ptr[1],32); | 333 | 14.3M | g[2]=ADD16((spx_word16_t)ptr[2],32); | 334 | 14.3M | gain_sum = (spx_word16_t)ptr[3]; | 335 | | | 336 | 14.3M | sum = compute_pitch_error(C16, g, pitch_control); | 337 | | | 338 | 14.3M | if (sum>best_sum && gain_sum<=max_gain) { | 339 | 525k | best_sum=sum; | 340 | 525k | best_cdbk=i; | 341 | 525k | } | 342 | 14.3M | } | 343 | | | 344 | 167k | return best_cdbk; | 345 | 167k | } |
ltp.c:pitch_gain_search_3tap_vq Line | Count | Source | 318 | 167k | { | 319 | 167k | const signed char *ptr=gain_cdbk; | 320 | 167k | int best_cdbk=0; | 321 | 167k | spx_word32_t best_sum=-VERY_LARGE32; | 322 | 167k | spx_word32_t sum=0; | 323 | 167k | spx_word16_t g[3]; | 324 | 167k | spx_word16_t pitch_control=64; | 325 | 167k | spx_word16_t gain_sum; | 326 | 167k | int i; | 327 | | | 328 | 14.5M | for (i=0;i<gain_cdbk_size;i++) { | 329 | | | 330 | 14.3M | ptr = gain_cdbk+4*i; | 331 | 14.3M | g[0]=ADD16((spx_word16_t)ptr[0],32); | 332 | 14.3M | g[1]=ADD16((spx_word16_t)ptr[1],32); | 333 | 14.3M | g[2]=ADD16((spx_word16_t)ptr[2],32); | 334 | 14.3M | gain_sum = (spx_word16_t)ptr[3]; | 335 | | | 336 | 14.3M | sum = compute_pitch_error(C16, g, pitch_control); | 337 | | | 338 | 14.3M | if (sum>best_sum && gain_sum<=max_gain) { | 339 | 525k | best_sum=sum; | 340 | 525k | best_cdbk=i; | 341 | 525k | } | 342 | 14.3M | } | 343 | | | 344 | 167k | return best_cdbk; | 345 | 167k | } |
|
346 | | #endif |
347 | | |
348 | | /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ |
349 | | static spx_word32_t pitch_gain_search_3tap( |
350 | | const spx_word16_t target[], /* Target vector */ |
351 | | const spx_coef_t ak[], /* LPCs for this subframe */ |
352 | | const spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ |
353 | | const spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ |
354 | | spx_sig_t exc[], /* Excitation */ |
355 | | const signed char *gain_cdbk, |
356 | | int gain_cdbk_size, |
357 | | int pitch, /* Pitch value */ |
358 | | int p, /* Number of LPC coeffs */ |
359 | | int nsf, /* Number of samples in subframe */ |
360 | | SpeexBits *bits, |
361 | | char *stack, |
362 | | const spx_word16_t *exc2, |
363 | | const spx_word16_t *r, |
364 | | spx_word16_t *new_target, |
365 | | int *cdbk_index, |
366 | | int plc_tuning, |
367 | | spx_word32_t cumul_gain, |
368 | | int scaledown |
369 | | ) |
370 | 167k | { |
371 | 167k | int i,j; |
372 | 167k | VARDECL(spx_word16_t *tmp1); |
373 | 167k | VARDECL(spx_word16_t *e); |
374 | 167k | spx_word16_t *x[3]; |
375 | 167k | spx_word32_t corr[3]; |
376 | 167k | spx_word32_t A[3][3]; |
377 | 167k | spx_word16_t gain[3]; |
378 | 167k | spx_word32_t err; |
379 | 167k | spx_word16_t max_gain=128; |
380 | 167k | int best_cdbk=0; |
381 | | |
382 | 167k | ALLOC(tmp1, 3*nsf, spx_word16_t); |
383 | 167k | ALLOC(e, nsf, spx_word16_t); |
384 | | |
385 | 167k | if (cumul_gain > 262144) |
386 | 1.52k | max_gain = 31; |
387 | | |
388 | 167k | x[0]=tmp1; |
389 | 167k | x[1]=tmp1+nsf; |
390 | 167k | x[2]=tmp1+2*nsf; |
391 | | |
392 | 6.86M | for (j=0;j<nsf;j++) |
393 | 6.70M | new_target[j] = target[j]; |
394 | | |
395 | 167k | { |
396 | 167k | int bound; |
397 | 167k | VARDECL(spx_mem_t *mm); |
398 | 167k | int pp=pitch-1; |
399 | 167k | ALLOC(mm, p, spx_mem_t); |
400 | 167k | bound = nsf; |
401 | 167k | if (nsf-pp>0) |
402 | 68.3k | bound = pp; |
403 | 5.79M | for (j=0;j<bound;j++) |
404 | 5.62M | e[j]=exc2[j-pp]; |
405 | 167k | bound = nsf; |
406 | 167k | if (nsf-pp-pitch>0) |
407 | 23.2k | bound = pp+pitch; |
408 | 1.14M | for (;j<bound;j++) |
409 | 974k | e[j]=exc2[j-pp-pitch]; |
410 | 269k | for (;j<nsf;j++) |
411 | 101k | e[j]=0; |
412 | | #ifdef FIXED_POINT |
413 | | /* Scale target and excitation down if needed (avoiding overflow) */ |
414 | 117k | if (scaledown) |
415 | 31.1k | { |
416 | 1.27M | for (j=0;j<nsf;j++) |
417 | 1.24M | e[j] = SHR16(e[j],1); |
418 | 1.27M | for (j=0;j<nsf;j++) |
419 | 1.24M | new_target[j] = SHR16(new_target[j],1); |
420 | 31.1k | } |
421 | | #endif |
422 | 1.84M | for (j=0;j<p;j++) |
423 | 1.67M | mm[j] = 0; |
424 | 167k | iir_mem16(e, ak, e, nsf, p, mm, stack); |
425 | 1.84M | for (j=0;j<p;j++) |
426 | 1.67M | mm[j] = 0; |
427 | 167k | filter10(e, awk1, awk2, e, nsf, mm, stack); |
428 | 6.86M | for (j=0;j<nsf;j++) |
429 | 6.70M | x[2][j] = e[j]; |
430 | 167k | } |
431 | 502k | for (i=1;i>=0;i--) |
432 | 335k | { |
433 | 335k | spx_word16_t e0=exc2[-pitch-1+i]; |
434 | | #ifdef FIXED_POINT |
435 | | /* Scale excitation down if needed (avoiding overflow) */ |
436 | 235k | if (scaledown) |
437 | 62.3k | e0 = SHR16(e0,1); |
438 | | #endif |
439 | 335k | x[i][0]=MULT16_16_Q14(r[0], e0); |
440 | 13.4M | for (j=0;j<nsf-1;j++) |
441 | 13.0M | x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); |
442 | 335k | } |
443 | | |
444 | 670k | for (i=0;i<3;i++) |
445 | 502k | corr[i]=inner_prod(x[i],new_target,nsf); |
446 | 670k | for (i=0;i<3;i++) |
447 | 1.50M | for (j=0;j<=i;j++) |
448 | 1.00M | A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); |
449 | | |
450 | 167k | { |
451 | 167k | spx_word32_t C[9]; |
452 | | #ifdef FIXED_POINT |
453 | | spx_word16_t C16[9]; |
454 | | #else |
455 | | spx_word16_t *C16=C; |
456 | | #endif |
457 | 167k | C[0]=corr[2]; |
458 | 167k | C[1]=corr[1]; |
459 | 167k | C[2]=corr[0]; |
460 | 167k | C[3]=A[1][2]; |
461 | 167k | C[4]=A[0][1]; |
462 | 167k | C[5]=A[0][2]; |
463 | 167k | C[6]=A[2][2]; |
464 | 167k | C[7]=A[1][1]; |
465 | 167k | C[8]=A[0][0]; |
466 | | |
467 | | /*plc_tuning *= 2;*/ |
468 | 167k | if (plc_tuning<2) |
469 | 0 | plc_tuning=2; |
470 | 167k | if (plc_tuning>30) |
471 | 0 | plc_tuning=30; |
472 | | #ifdef FIXED_POINT |
473 | 117k | C[0] = SHL32(C[0],1); |
474 | 117k | C[1] = SHL32(C[1],1); |
475 | 117k | C[2] = SHL32(C[2],1); |
476 | 117k | C[3] = SHL32(C[3],1); |
477 | 117k | C[4] = SHL32(C[4],1); |
478 | 117k | C[5] = SHL32(C[5],1); |
479 | 117k | C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); |
480 | 117k | C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); |
481 | 117k | C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]); |
482 | | normalize16(C, C16, 32767, 9); |
483 | | #else |
484 | | C[6]*=.5*(1+.02*plc_tuning); |
485 | | C[7]*=.5*(1+.02*plc_tuning); |
486 | | C[8]*=.5*(1+.02*plc_tuning); |
487 | | #endif |
488 | | |
489 | 167k | best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); |
490 | | |
491 | | #ifdef FIXED_POINT |
492 | 117k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); |
493 | 117k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); |
494 | 117k | gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]); |
495 | | /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/ |
496 | | #else |
497 | | gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5; |
498 | | gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5; |
499 | | gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5; |
500 | | #endif |
501 | 167k | *cdbk_index=best_cdbk; |
502 | 167k | } |
503 | | |
504 | 167k | SPEEX_MEMSET(exc, 0, nsf); |
505 | 670k | for (i=0;i<3;i++) |
506 | 502k | { |
507 | 502k | int j; |
508 | 502k | int tmp1, tmp3; |
509 | 502k | int pp=pitch+1-i; |
510 | 502k | tmp1=nsf; |
511 | 502k | if (tmp1>pp) |
512 | 198k | tmp1=pp; |
513 | 17.5M | for (j=0;j<tmp1;j++) |
514 | 17.0M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); |
515 | 502k | tmp3=nsf; |
516 | 502k | if (tmp3>pp+pitch) |
517 | 60.1k | tmp3=pp+pitch; |
518 | 3.28M | for (j=tmp1;j<tmp3;j++) |
519 | 2.78M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); |
520 | 502k | } |
521 | 6.86M | for (i=0;i<nsf;i++) |
522 | 6.70M | { |
523 | 6.70M | spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), |
524 | 6.70M | MULT16_16(gain[2],x[0][i])); |
525 | 6.70M | new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); |
526 | 6.70M | } |
527 | 167k | err = inner_prod(new_target, new_target, nsf); |
528 | | |
529 | 167k | return err; |
530 | 167k | } ltp.c:pitch_gain_search_3tap Line | Count | Source | 370 | 49.6k | { | 371 | 49.6k | int i,j; | 372 | 49.6k | VARDECL(spx_word16_t *tmp1); | 373 | 49.6k | VARDECL(spx_word16_t *e); | 374 | 49.6k | spx_word16_t *x[3]; | 375 | 49.6k | spx_word32_t corr[3]; | 376 | 49.6k | spx_word32_t A[3][3]; | 377 | 49.6k | spx_word16_t gain[3]; | 378 | 49.6k | spx_word32_t err; | 379 | 49.6k | spx_word16_t max_gain=128; | 380 | 49.6k | int best_cdbk=0; | 381 | | | 382 | 49.6k | ALLOC(tmp1, 3*nsf, spx_word16_t); | 383 | 49.6k | ALLOC(e, nsf, spx_word16_t); | 384 | | | 385 | 49.6k | if (cumul_gain > 262144) | 386 | 472 | max_gain = 31; | 387 | | | 388 | 49.6k | x[0]=tmp1; | 389 | 49.6k | x[1]=tmp1+nsf; | 390 | 49.6k | x[2]=tmp1+2*nsf; | 391 | | | 392 | 2.03M | for (j=0;j<nsf;j++) | 393 | 1.98M | new_target[j] = target[j]; | 394 | | | 395 | 49.6k | { | 396 | 49.6k | int bound; | 397 | 49.6k | VARDECL(spx_mem_t *mm); | 398 | 49.6k | int pp=pitch-1; | 399 | 49.6k | ALLOC(mm, p, spx_mem_t); | 400 | 49.6k | bound = nsf; | 401 | 49.6k | if (nsf-pp>0) | 402 | 24.2k | bound = pp; | 403 | 1.63M | for (j=0;j<bound;j++) | 404 | 1.58M | e[j]=exc2[j-pp]; | 405 | 49.6k | bound = nsf; | 406 | 49.6k | if (nsf-pp-pitch>0) | 407 | 8.31k | bound = pp+pitch; | 408 | 407k | for (;j<bound;j++) | 409 | 357k | e[j]=exc2[j-pp-pitch]; | 410 | 87.7k | for (;j<nsf;j++) | 411 | 38.1k | e[j]=0; | 412 | | #ifdef FIXED_POINT | 413 | | /* Scale target and excitation down if needed (avoiding overflow) */ | 414 | | if (scaledown) | 415 | | { | 416 | | for (j=0;j<nsf;j++) | 417 | | e[j] = SHR16(e[j],1); | 418 | | for (j=0;j<nsf;j++) | 419 | | new_target[j] = SHR16(new_target[j],1); | 420 | | } | 421 | | #endif | 422 | 545k | for (j=0;j<p;j++) | 423 | 496k | mm[j] = 0; | 424 | 49.6k | iir_mem16(e, ak, e, nsf, p, mm, stack); | 425 | 545k | for (j=0;j<p;j++) | 426 | 496k | mm[j] = 0; | 427 | 49.6k | filter10(e, awk1, awk2, e, nsf, mm, stack); | 428 | 2.03M | for (j=0;j<nsf;j++) | 429 | 1.98M | x[2][j] = e[j]; | 430 | 49.6k | } | 431 | 148k | for (i=1;i>=0;i--) | 432 | 99.2k | { | 433 | 99.2k | spx_word16_t e0=exc2[-pitch-1+i]; | 434 | | #ifdef FIXED_POINT | 435 | | /* Scale excitation down if needed (avoiding overflow) */ | 436 | | if (scaledown) | 437 | | e0 = SHR16(e0,1); | 438 | | #endif | 439 | 99.2k | x[i][0]=MULT16_16_Q14(r[0], e0); | 440 | 3.96M | for (j=0;j<nsf-1;j++) | 441 | 3.86M | x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); | 442 | 99.2k | } | 443 | | | 444 | 198k | for (i=0;i<3;i++) | 445 | 148k | corr[i]=inner_prod(x[i],new_target,nsf); | 446 | 198k | for (i=0;i<3;i++) | 447 | 446k | for (j=0;j<=i;j++) | 448 | 297k | A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); | 449 | | | 450 | 49.6k | { | 451 | 49.6k | spx_word32_t C[9]; | 452 | | #ifdef FIXED_POINT | 453 | | spx_word16_t C16[9]; | 454 | | #else | 455 | 49.6k | spx_word16_t *C16=C; | 456 | 49.6k | #endif | 457 | 49.6k | C[0]=corr[2]; | 458 | 49.6k | C[1]=corr[1]; | 459 | 49.6k | C[2]=corr[0]; | 460 | 49.6k | C[3]=A[1][2]; | 461 | 49.6k | C[4]=A[0][1]; | 462 | 49.6k | C[5]=A[0][2]; | 463 | 49.6k | C[6]=A[2][2]; | 464 | 49.6k | C[7]=A[1][1]; | 465 | 49.6k | C[8]=A[0][0]; | 466 | | | 467 | | /*plc_tuning *= 2;*/ | 468 | 49.6k | if (plc_tuning<2) | 469 | 0 | plc_tuning=2; | 470 | 49.6k | if (plc_tuning>30) | 471 | 0 | plc_tuning=30; | 472 | | #ifdef FIXED_POINT | 473 | | C[0] = SHL32(C[0],1); | 474 | | C[1] = SHL32(C[1],1); | 475 | | C[2] = SHL32(C[2],1); | 476 | | C[3] = SHL32(C[3],1); | 477 | | C[4] = SHL32(C[4],1); | 478 | | C[5] = SHL32(C[5],1); | 479 | | C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); | 480 | | C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); | 481 | | C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]); | 482 | | normalize16(C, C16, 32767, 9); | 483 | | #else | 484 | 49.6k | C[6]*=.5*(1+.02*plc_tuning); | 485 | 49.6k | C[7]*=.5*(1+.02*plc_tuning); | 486 | 49.6k | C[8]*=.5*(1+.02*plc_tuning); | 487 | 49.6k | #endif | 488 | | | 489 | 49.6k | best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); | 490 | | | 491 | | #ifdef FIXED_POINT | 492 | | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); | 493 | | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); | 494 | | gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]); | 495 | | /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/ | 496 | | #else | 497 | 49.6k | gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5; | 498 | 49.6k | gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5; | 499 | 49.6k | gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5; | 500 | 49.6k | #endif | 501 | 49.6k | *cdbk_index=best_cdbk; | 502 | 49.6k | } | 503 | | | 504 | 49.6k | SPEEX_MEMSET(exc, 0, nsf); | 505 | 198k | for (i=0;i<3;i++) | 506 | 148k | { | 507 | 148k | int j; | 508 | 148k | int tmp1, tmp3; | 509 | 148k | int pp=pitch+1-i; | 510 | 148k | tmp1=nsf; | 511 | 148k | if (tmp1>pp) | 512 | 71.5k | tmp1=pp; | 513 | 4.98M | for (j=0;j<tmp1;j++) | 514 | 4.83M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); | 515 | 148k | tmp3=nsf; | 516 | 148k | if (tmp3>pp+pitch) | 517 | 22.0k | tmp3=pp+pitch; | 518 | 1.17M | for (j=tmp1;j<tmp3;j++) | 519 | 1.02M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); | 520 | 148k | } | 521 | 2.03M | for (i=0;i<nsf;i++) | 522 | 1.98M | { | 523 | 1.98M | spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), | 524 | 1.98M | MULT16_16(gain[2],x[0][i])); | 525 | 1.98M | new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); | 526 | 1.98M | } | 527 | 49.6k | err = inner_prod(new_target, new_target, nsf); | 528 | | | 529 | 49.6k | return err; | 530 | 49.6k | } |
ltp.c:pitch_gain_search_3tap Line | Count | Source | 370 | 117k | { | 371 | 117k | int i,j; | 372 | 117k | VARDECL(spx_word16_t *tmp1); | 373 | 117k | VARDECL(spx_word16_t *e); | 374 | 117k | spx_word16_t *x[3]; | 375 | 117k | spx_word32_t corr[3]; | 376 | 117k | spx_word32_t A[3][3]; | 377 | 117k | spx_word16_t gain[3]; | 378 | 117k | spx_word32_t err; | 379 | 117k | spx_word16_t max_gain=128; | 380 | 117k | int best_cdbk=0; | 381 | | | 382 | 117k | ALLOC(tmp1, 3*nsf, spx_word16_t); | 383 | 117k | ALLOC(e, nsf, spx_word16_t); | 384 | | | 385 | 117k | if (cumul_gain > 262144) | 386 | 1.05k | max_gain = 31; | 387 | | | 388 | 117k | x[0]=tmp1; | 389 | 117k | x[1]=tmp1+nsf; | 390 | 117k | x[2]=tmp1+2*nsf; | 391 | | | 392 | 4.83M | for (j=0;j<nsf;j++) | 393 | 4.71M | new_target[j] = target[j]; | 394 | | | 395 | 117k | { | 396 | 117k | int bound; | 397 | 117k | VARDECL(spx_mem_t *mm); | 398 | 117k | int pp=pitch-1; | 399 | 117k | ALLOC(mm, p, spx_mem_t); | 400 | 117k | bound = nsf; | 401 | 117k | if (nsf-pp>0) | 402 | 44.1k | bound = pp; | 403 | 4.15M | for (j=0;j<bound;j++) | 404 | 4.03M | e[j]=exc2[j-pp]; | 405 | 117k | bound = nsf; | 406 | 117k | if (nsf-pp-pitch>0) | 407 | 14.9k | bound = pp+pitch; | 408 | 734k | for (;j<bound;j++) | 409 | 616k | e[j]=exc2[j-pp-pitch]; | 410 | 181k | for (;j<nsf;j++) | 411 | 63.4k | e[j]=0; | 412 | 117k | #ifdef FIXED_POINT | 413 | | /* Scale target and excitation down if needed (avoiding overflow) */ | 414 | 117k | if (scaledown) | 415 | 31.1k | { | 416 | 1.27M | for (j=0;j<nsf;j++) | 417 | 1.24M | e[j] = SHR16(e[j],1); | 418 | 1.27M | for (j=0;j<nsf;j++) | 419 | 1.24M | new_target[j] = SHR16(new_target[j],1); | 420 | 31.1k | } | 421 | 117k | #endif | 422 | 1.29M | for (j=0;j<p;j++) | 423 | 1.17M | mm[j] = 0; | 424 | 117k | iir_mem16(e, ak, e, nsf, p, mm, stack); | 425 | 1.29M | for (j=0;j<p;j++) | 426 | 1.17M | mm[j] = 0; | 427 | 117k | filter10(e, awk1, awk2, e, nsf, mm, stack); | 428 | 4.83M | for (j=0;j<nsf;j++) | 429 | 4.71M | x[2][j] = e[j]; | 430 | 117k | } | 431 | 353k | for (i=1;i>=0;i--) | 432 | 235k | { | 433 | 235k | spx_word16_t e0=exc2[-pitch-1+i]; | 434 | 235k | #ifdef FIXED_POINT | 435 | | /* Scale excitation down if needed (avoiding overflow) */ | 436 | 235k | if (scaledown) | 437 | 62.3k | e0 = SHR16(e0,1); | 438 | 235k | #endif | 439 | 235k | x[i][0]=MULT16_16_Q14(r[0], e0); | 440 | 9.43M | for (j=0;j<nsf-1;j++) | 441 | 9.19M | x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); | 442 | 235k | } | 443 | | | 444 | 471k | for (i=0;i<3;i++) | 445 | 353k | corr[i]=inner_prod(x[i],new_target,nsf); | 446 | 471k | for (i=0;i<3;i++) | 447 | 1.06M | for (j=0;j<=i;j++) | 448 | 707k | A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); | 449 | | | 450 | 117k | { | 451 | 117k | spx_word32_t C[9]; | 452 | 117k | #ifdef FIXED_POINT | 453 | 117k | spx_word16_t C16[9]; | 454 | | #else | 455 | | spx_word16_t *C16=C; | 456 | | #endif | 457 | 117k | C[0]=corr[2]; | 458 | 117k | C[1]=corr[1]; | 459 | 117k | C[2]=corr[0]; | 460 | 117k | C[3]=A[1][2]; | 461 | 117k | C[4]=A[0][1]; | 462 | 117k | C[5]=A[0][2]; | 463 | 117k | C[6]=A[2][2]; | 464 | 117k | C[7]=A[1][1]; | 465 | 117k | C[8]=A[0][0]; | 466 | | | 467 | | /*plc_tuning *= 2;*/ | 468 | 117k | if (plc_tuning<2) | 469 | 0 | plc_tuning=2; | 470 | 117k | if (plc_tuning>30) | 471 | 0 | plc_tuning=30; | 472 | 117k | #ifdef FIXED_POINT | 473 | 117k | C[0] = SHL32(C[0],1); | 474 | 117k | C[1] = SHL32(C[1],1); | 475 | 117k | C[2] = SHL32(C[2],1); | 476 | 117k | C[3] = SHL32(C[3],1); | 477 | 117k | C[4] = SHL32(C[4],1); | 478 | 117k | C[5] = SHL32(C[5],1); | 479 | 117k | C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); | 480 | 117k | C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); | 481 | 117k | C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]); | 482 | 117k | normalize16(C, C16, 32767, 9); | 483 | | #else | 484 | | C[6]*=.5*(1+.02*plc_tuning); | 485 | | C[7]*=.5*(1+.02*plc_tuning); | 486 | | C[8]*=.5*(1+.02*plc_tuning); | 487 | | #endif | 488 | | | 489 | 117k | best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); | 490 | | | 491 | 117k | #ifdef FIXED_POINT | 492 | 117k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); | 493 | 117k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); | 494 | 117k | gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+2]); | 495 | | /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/ | 496 | | #else | 497 | | gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5; | 498 | | gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5; | 499 | | gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5; | 500 | | #endif | 501 | 117k | *cdbk_index=best_cdbk; | 502 | 117k | } | 503 | | | 504 | 117k | SPEEX_MEMSET(exc, 0, nsf); | 505 | 471k | for (i=0;i<3;i++) | 506 | 353k | { | 507 | 353k | int j; | 508 | 353k | int tmp1, tmp3; | 509 | 353k | int pp=pitch+1-i; | 510 | 353k | tmp1=nsf; | 511 | 353k | if (tmp1>pp) | 512 | 126k | tmp1=pp; | 513 | 12.5M | for (j=0;j<tmp1;j++) | 514 | 12.2M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); | 515 | 353k | tmp3=nsf; | 516 | 353k | if (tmp3>pp+pitch) | 517 | 38.0k | tmp3=pp+pitch; | 518 | 2.11M | for (j=tmp1;j<tmp3;j++) | 519 | 1.76M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); | 520 | 353k | } | 521 | 4.83M | for (i=0;i<nsf;i++) | 522 | 4.71M | { | 523 | 4.71M | spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), | 524 | 4.71M | MULT16_16(gain[2],x[0][i])); | 525 | 4.71M | new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); | 526 | 4.71M | } | 527 | 117k | err = inner_prod(new_target, new_target, nsf); | 528 | | | 529 | 117k | return err; | 530 | 117k | } |
|
531 | | |
532 | | /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ |
533 | | int pitch_search_3tap( |
534 | | spx_word16_t target[], /* Target vector */ |
535 | | spx_word16_t *sw, |
536 | | spx_coef_t ak[], /* LPCs for this subframe */ |
537 | | spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ |
538 | | spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ |
539 | | spx_sig_t exc[], /* Excitation */ |
540 | | const void *par, |
541 | | int start, /* Smallest pitch value allowed */ |
542 | | int end, /* Largest pitch value allowed */ |
543 | | spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ |
544 | | int p, /* Number of LPC coeffs */ |
545 | | int nsf, /* Number of samples in subframe */ |
546 | | SpeexBits *bits, |
547 | | char *stack, |
548 | | spx_word16_t *exc2, |
549 | | spx_word16_t *r, |
550 | | int complexity, |
551 | | int cdbk_offset, |
552 | | int plc_tuning, |
553 | | spx_word32_t *cumul_gain |
554 | | ) |
555 | 37.8k | { |
556 | 37.8k | int i; |
557 | 37.8k | int cdbk_index, pitch=0, best_gain_index=0; |
558 | 37.8k | VARDECL(spx_sig_t *best_exc); |
559 | 37.8k | VARDECL(spx_word16_t *new_target); |
560 | 37.8k | VARDECL(spx_word16_t *best_target); |
561 | 37.8k | int best_pitch=0; |
562 | 37.8k | spx_word32_t err, best_err=-1; |
563 | 37.8k | int N; |
564 | 37.8k | const ltp_params *params; |
565 | 37.8k | const signed char *gain_cdbk; |
566 | 37.8k | int gain_cdbk_size; |
567 | 37.8k | int scaledown=0; |
568 | | |
569 | 37.8k | VARDECL(int *nbest); |
570 | | |
571 | 37.8k | params = (const ltp_params*) par; |
572 | 37.8k | gain_cdbk_size = 1<<params->gain_bits; |
573 | 37.8k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; |
574 | | |
575 | 37.8k | N=complexity; |
576 | 37.8k | if (N>10) |
577 | 0 | N=10; |
578 | 37.8k | if (N<1) |
579 | 4.94k | N=1; |
580 | | |
581 | 37.8k | ALLOC(nbest, N, int); |
582 | 37.8k | params = (const ltp_params*) par; |
583 | | |
584 | 37.8k | if (end<start) |
585 | 2.24k | { |
586 | 2.24k | speex_bits_pack(bits, 0, params->pitch_bits); |
587 | 2.24k | speex_bits_pack(bits, 0, params->gain_bits); |
588 | 2.24k | SPEEX_MEMSET(exc, 0, nsf); |
589 | 2.24k | return start; |
590 | 2.24k | } |
591 | | |
592 | | #ifdef FIXED_POINT |
593 | | /* Check if we need to scale everything down in the pitch search to avoid overflows */ |
594 | 917k | for (i=0;i<nsf;i++) |
595 | 896k | { |
596 | 896k | if (ABS16(target[i])>16383) |
597 | 4.77k | { |
598 | 4.77k | scaledown=1; |
599 | 4.77k | break; |
600 | 4.77k | } |
601 | 896k | } |
602 | 2.68M | for (i=-end;i<0;i++) |
603 | 2.66M | { |
604 | 2.66M | if (ABS16(exc2[i])>16383) |
605 | 4.50k | { |
606 | 4.50k | scaledown=1; |
607 | 4.50k | break; |
608 | 4.50k | } |
609 | 2.66M | } |
610 | | #endif |
611 | 35.6k | if (N>end-start+1) |
612 | 4.38k | N=end-start+1; |
613 | 35.6k | if (end != start) |
614 | 30.0k | open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); |
615 | 5.57k | else |
616 | 5.57k | nbest[0] = start; |
617 | | |
618 | 35.6k | ALLOC(best_exc, nsf, spx_sig_t); |
619 | 35.6k | ALLOC(new_target, nsf, spx_word16_t); |
620 | 35.6k | ALLOC(best_target, nsf, spx_word16_t); |
621 | | |
622 | 203k | for (i=0;i<N;i++) |
623 | 167k | { |
624 | 167k | pitch=nbest[i]; |
625 | 167k | SPEEX_MEMSET(exc, 0, nsf); |
626 | 167k | err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, |
627 | 167k | bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); |
628 | 167k | if (err<best_err || best_err<0) |
629 | 48.2k | { |
630 | 48.2k | SPEEX_COPY(best_exc, exc, nsf); |
631 | 48.2k | SPEEX_COPY(best_target, new_target, nsf); |
632 | 48.2k | best_err=err; |
633 | 48.2k | best_pitch=pitch; |
634 | 48.2k | best_gain_index=cdbk_index; |
635 | 48.2k | } |
636 | 167k | } |
637 | | /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ |
638 | 9.65k | speex_bits_pack(bits, best_pitch-start, params->pitch_bits); |
639 | 9.65k | speex_bits_pack(bits, best_gain_index, params->gain_bits); |
640 | | #ifdef FIXED_POINT |
641 | 25.9k | *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain)); |
642 | | #else |
643 | 9.65k | *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3]; |
644 | | #endif |
645 | | /*printf ("%f\n", cumul_gain);*/ |
646 | | /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ |
647 | 35.6k | SPEEX_COPY(exc, best_exc, nsf); |
648 | 35.6k | SPEEX_COPY(target, best_target, nsf); |
649 | | #ifdef FIXED_POINT |
650 | | /* Scale target back up if needed */ |
651 | 25.9k | if (scaledown) |
652 | 6.57k | { |
653 | 269k | for (i=0;i<nsf;i++) |
654 | 263k | target[i]=SHL16(target[i],1); |
655 | 6.57k | } |
656 | | #endif |
657 | 9.65k | return pitch; |
658 | 37.8k | } Line | Count | Source | 555 | 10.4k | { | 556 | 10.4k | int i; | 557 | 10.4k | int cdbk_index, pitch=0, best_gain_index=0; | 558 | 10.4k | VARDECL(spx_sig_t *best_exc); | 559 | 10.4k | VARDECL(spx_word16_t *new_target); | 560 | 10.4k | VARDECL(spx_word16_t *best_target); | 561 | 10.4k | int best_pitch=0; | 562 | 10.4k | spx_word32_t err, best_err=-1; | 563 | 10.4k | int N; | 564 | 10.4k | const ltp_params *params; | 565 | 10.4k | const signed char *gain_cdbk; | 566 | 10.4k | int gain_cdbk_size; | 567 | 10.4k | int scaledown=0; | 568 | | | 569 | 10.4k | VARDECL(int *nbest); | 570 | | | 571 | 10.4k | params = (const ltp_params*) par; | 572 | 10.4k | gain_cdbk_size = 1<<params->gain_bits; | 573 | 10.4k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 574 | | | 575 | 10.4k | N=complexity; | 576 | 10.4k | if (N>10) | 577 | 0 | N=10; | 578 | 10.4k | if (N<1) | 579 | 1.39k | N=1; | 580 | | | 581 | 10.4k | ALLOC(nbest, N, int); | 582 | 10.4k | params = (const ltp_params*) par; | 583 | | | 584 | 10.4k | if (end<start) | 585 | 750 | { | 586 | 750 | speex_bits_pack(bits, 0, params->pitch_bits); | 587 | 750 | speex_bits_pack(bits, 0, params->gain_bits); | 588 | 750 | SPEEX_MEMSET(exc, 0, nsf); | 589 | 750 | return start; | 590 | 750 | } | 591 | | | 592 | | #ifdef FIXED_POINT | 593 | | /* Check if we need to scale everything down in the pitch search to avoid overflows */ | 594 | | for (i=0;i<nsf;i++) | 595 | | { | 596 | | if (ABS16(target[i])>16383) | 597 | | { | 598 | | scaledown=1; | 599 | | break; | 600 | | } | 601 | | } | 602 | | for (i=-end;i<0;i++) | 603 | | { | 604 | | if (ABS16(exc2[i])>16383) | 605 | | { | 606 | | scaledown=1; | 607 | | break; | 608 | | } | 609 | | } | 610 | | #endif | 611 | 9.65k | if (N>end-start+1) | 612 | 928 | N=end-start+1; | 613 | 9.65k | if (end != start) | 614 | 8.48k | open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); | 615 | 1.17k | else | 616 | 1.17k | nbest[0] = start; | 617 | | | 618 | 9.65k | ALLOC(best_exc, nsf, spx_sig_t); | 619 | 9.65k | ALLOC(new_target, nsf, spx_word16_t); | 620 | 9.65k | ALLOC(best_target, nsf, spx_word16_t); | 621 | | | 622 | 59.2k | for (i=0;i<N;i++) | 623 | 49.6k | { | 624 | 49.6k | pitch=nbest[i]; | 625 | 49.6k | SPEEX_MEMSET(exc, 0, nsf); | 626 | 49.6k | err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, | 627 | 49.6k | bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); | 628 | 49.6k | if (err<best_err || best_err<0) | 629 | 12.1k | { | 630 | 12.1k | SPEEX_COPY(best_exc, exc, nsf); | 631 | 12.1k | SPEEX_COPY(best_target, new_target, nsf); | 632 | 12.1k | best_err=err; | 633 | 12.1k | best_pitch=pitch; | 634 | 12.1k | best_gain_index=cdbk_index; | 635 | 12.1k | } | 636 | 49.6k | } | 637 | | /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ | 638 | 9.65k | speex_bits_pack(bits, best_pitch-start, params->pitch_bits); | 639 | 9.65k | speex_bits_pack(bits, best_gain_index, params->gain_bits); | 640 | | #ifdef FIXED_POINT | 641 | | *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain)); | 642 | | #else | 643 | 9.65k | *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3]; | 644 | 9.65k | #endif | 645 | | /*printf ("%f\n", cumul_gain);*/ | 646 | | /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ | 647 | 9.65k | SPEEX_COPY(exc, best_exc, nsf); | 648 | 9.65k | SPEEX_COPY(target, best_target, nsf); | 649 | | #ifdef FIXED_POINT | 650 | | /* Scale target back up if needed */ | 651 | | if (scaledown) | 652 | | { | 653 | | for (i=0;i<nsf;i++) | 654 | | target[i]=SHL16(target[i],1); | 655 | | } | 656 | | #endif | 657 | 9.65k | return pitch; | 658 | 10.4k | } |
Line | Count | Source | 555 | 27.4k | { | 556 | 27.4k | int i; | 557 | 27.4k | int cdbk_index, pitch=0, best_gain_index=0; | 558 | 27.4k | VARDECL(spx_sig_t *best_exc); | 559 | 27.4k | VARDECL(spx_word16_t *new_target); | 560 | 27.4k | VARDECL(spx_word16_t *best_target); | 561 | 27.4k | int best_pitch=0; | 562 | 27.4k | spx_word32_t err, best_err=-1; | 563 | 27.4k | int N; | 564 | 27.4k | const ltp_params *params; | 565 | 27.4k | const signed char *gain_cdbk; | 566 | 27.4k | int gain_cdbk_size; | 567 | 27.4k | int scaledown=0; | 568 | | | 569 | 27.4k | VARDECL(int *nbest); | 570 | | | 571 | 27.4k | params = (const ltp_params*) par; | 572 | 27.4k | gain_cdbk_size = 1<<params->gain_bits; | 573 | 27.4k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 574 | | | 575 | 27.4k | N=complexity; | 576 | 27.4k | if (N>10) | 577 | 0 | N=10; | 578 | 27.4k | if (N<1) | 579 | 3.55k | N=1; | 580 | | | 581 | 27.4k | ALLOC(nbest, N, int); | 582 | 27.4k | params = (const ltp_params*) par; | 583 | | | 584 | 27.4k | if (end<start) | 585 | 1.49k | { | 586 | 1.49k | speex_bits_pack(bits, 0, params->pitch_bits); | 587 | 1.49k | speex_bits_pack(bits, 0, params->gain_bits); | 588 | 1.49k | SPEEX_MEMSET(exc, 0, nsf); | 589 | 1.49k | return start; | 590 | 1.49k | } | 591 | | | 592 | 25.9k | #ifdef FIXED_POINT | 593 | | /* Check if we need to scale everything down in the pitch search to avoid overflows */ | 594 | 917k | for (i=0;i<nsf;i++) | 595 | 896k | { | 596 | 896k | if (ABS16(target[i])>16383) | 597 | 4.77k | { | 598 | 4.77k | scaledown=1; | 599 | 4.77k | break; | 600 | 4.77k | } | 601 | 896k | } | 602 | 2.68M | for (i=-end;i<0;i++) | 603 | 2.66M | { | 604 | 2.66M | if (ABS16(exc2[i])>16383) | 605 | 4.50k | { | 606 | 4.50k | scaledown=1; | 607 | 4.50k | break; | 608 | 4.50k | } | 609 | 2.66M | } | 610 | 25.9k | #endif | 611 | 25.9k | if (N>end-start+1) | 612 | 3.45k | N=end-start+1; | 613 | 25.9k | if (end != start) | 614 | 21.5k | open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); | 615 | 4.40k | else | 616 | 4.40k | nbest[0] = start; | 617 | | | 618 | 25.9k | ALLOC(best_exc, nsf, spx_sig_t); | 619 | 25.9k | ALLOC(new_target, nsf, spx_word16_t); | 620 | 25.9k | ALLOC(best_target, nsf, spx_word16_t); | 621 | | | 622 | 143k | for (i=0;i<N;i++) | 623 | 117k | { | 624 | 117k | pitch=nbest[i]; | 625 | 117k | SPEEX_MEMSET(exc, 0, nsf); | 626 | 117k | err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, | 627 | 117k | bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); | 628 | 117k | if (err<best_err || best_err<0) | 629 | 36.1k | { | 630 | 36.1k | SPEEX_COPY(best_exc, exc, nsf); | 631 | 36.1k | SPEEX_COPY(best_target, new_target, nsf); | 632 | 36.1k | best_err=err; | 633 | 36.1k | best_pitch=pitch; | 634 | 36.1k | best_gain_index=cdbk_index; | 635 | 36.1k | } | 636 | 117k | } | 637 | | /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ | 638 | 25.9k | speex_bits_pack(bits, best_pitch-start, params->pitch_bits); | 639 | 25.9k | speex_bits_pack(bits, best_gain_index, params->gain_bits); | 640 | 25.9k | #ifdef FIXED_POINT | 641 | 25.9k | *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain)); | 642 | | #else | 643 | | *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3]; | 644 | | #endif | 645 | | /*printf ("%f\n", cumul_gain);*/ | 646 | | /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ | 647 | 25.9k | SPEEX_COPY(exc, best_exc, nsf); | 648 | 25.9k | SPEEX_COPY(target, best_target, nsf); | 649 | 25.9k | #ifdef FIXED_POINT | 650 | | /* Scale target back up if needed */ | 651 | 25.9k | if (scaledown) | 652 | 6.57k | { | 653 | 269k | for (i=0;i<nsf;i++) | 654 | 263k | target[i]=SHL16(target[i],1); | 655 | 6.57k | } | 656 | 25.9k | #endif | 657 | 25.9k | return pitch; | 658 | 27.4k | } |
|
659 | | #endif /* DISABLE_ENCODER */ |
660 | | |
661 | | #ifndef DISABLE_DECODER |
662 | | void pitch_unquant_3tap( |
663 | | spx_word16_t exc[], /* Input excitation */ |
664 | | spx_word32_t exc_out[], /* Output excitation */ |
665 | | int start, /* Smallest pitch value allowed */ |
666 | | int end, /* Largest pitch value allowed */ |
667 | | spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ |
668 | | const void *par, |
669 | | int nsf, /* Number of samples in subframe */ |
670 | | int *pitch_val, |
671 | | spx_word16_t *gain_val, |
672 | | SpeexBits *bits, |
673 | | char *stack, |
674 | | int count_lost, |
675 | | int subframe_offset, |
676 | | spx_word16_t last_pitch_gain, |
677 | | int cdbk_offset |
678 | | ) |
679 | 120k | { |
680 | 120k | int i; |
681 | 120k | int pitch; |
682 | 120k | int gain_index; |
683 | 120k | spx_word16_t gain[3]; |
684 | 120k | const signed char *gain_cdbk; |
685 | 120k | int gain_cdbk_size; |
686 | 120k | const ltp_params *params; |
687 | | |
688 | 120k | params = (const ltp_params*) par; |
689 | 120k | gain_cdbk_size = 1<<params->gain_bits; |
690 | 120k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; |
691 | | |
692 | 120k | pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); |
693 | 120k | pitch += start; |
694 | 120k | gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); |
695 | | /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ |
696 | | #ifdef FIXED_POINT |
697 | 60.3k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); |
698 | 60.3k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); |
699 | 60.3k | gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]); |
700 | | #else |
701 | | gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5; |
702 | | gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5; |
703 | | gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5; |
704 | | #endif |
705 | | |
706 | 120k | if (count_lost && pitch > subframe_offset) |
707 | 0 | { |
708 | 0 | spx_word16_t gain_sum; |
709 | 0 | if (1) { |
710 | | #ifdef FIXED_POINT |
711 | 0 | spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1); |
712 | 0 | if (tmp>62) |
713 | 0 | tmp=62; |
714 | | #else |
715 | 0 | spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain; |
716 | 0 | if (tmp>.95) |
717 | 0 | tmp=.95; |
718 | | #endif |
719 | 0 | gain_sum = gain_3tap_to_1tap(gain); |
720 | |
|
721 | 0 | if (gain_sum > tmp) |
722 | 0 | { |
723 | 0 | spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum); |
724 | 0 | for (i=0;i<3;i++) |
725 | 0 | gain[i]=MULT16_16_Q14(fact,gain[i]); |
726 | 0 | } |
727 | |
|
728 | 0 | } |
729 | |
|
730 | 0 | } |
731 | | |
732 | 120k | *pitch_val = pitch; |
733 | 120k | gain_val[0]=gain[0]; |
734 | 120k | gain_val[1]=gain[1]; |
735 | 120k | gain_val[2]=gain[2]; |
736 | 120k | gain[0] = SHL16(gain[0],7); |
737 | 120k | gain[1] = SHL16(gain[1],7); |
738 | 120k | gain[2] = SHL16(gain[2],7); |
739 | 120k | SPEEX_MEMSET(exc_out, 0, nsf); |
740 | 482k | for (i=0;i<3;i++) |
741 | 362k | { |
742 | 362k | int j; |
743 | 362k | int tmp1, tmp3; |
744 | 362k | int pp=pitch+1-i; |
745 | 362k | tmp1=nsf; |
746 | 362k | if (tmp1>pp) |
747 | 295k | tmp1=pp; |
748 | 8.28M | for (j=0;j<tmp1;j++) |
749 | 7.92M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); |
750 | 362k | tmp3=nsf; |
751 | 362k | if (tmp3>pp+pitch) |
752 | 273k | tmp3=pp+pitch; |
753 | 5.29M | for (j=tmp1;j<tmp3;j++) |
754 | 4.93M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); |
755 | 362k | } |
756 | | /*for (i=0;i<nsf;i++) |
757 | | exc[i]=PSHR32(exc32[i],13);*/ |
758 | 120k | } Line | Count | Source | 679 | 60.3k | { | 680 | 60.3k | int i; | 681 | 60.3k | int pitch; | 682 | 60.3k | int gain_index; | 683 | 60.3k | spx_word16_t gain[3]; | 684 | 60.3k | const signed char *gain_cdbk; | 685 | 60.3k | int gain_cdbk_size; | 686 | 60.3k | const ltp_params *params; | 687 | | | 688 | 60.3k | params = (const ltp_params*) par; | 689 | 60.3k | gain_cdbk_size = 1<<params->gain_bits; | 690 | 60.3k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 691 | | | 692 | 60.3k | pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); | 693 | 60.3k | pitch += start; | 694 | 60.3k | gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); | 695 | | /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ | 696 | | #ifdef FIXED_POINT | 697 | | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); | 698 | | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); | 699 | | gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]); | 700 | | #else | 701 | 60.3k | gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5; | 702 | 60.3k | gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5; | 703 | 60.3k | gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5; | 704 | 60.3k | #endif | 705 | | | 706 | 60.3k | if (count_lost && pitch > subframe_offset) | 707 | 0 | { | 708 | 0 | spx_word16_t gain_sum; | 709 | 0 | if (1) { | 710 | | #ifdef FIXED_POINT | 711 | | spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1); | 712 | | if (tmp>62) | 713 | | tmp=62; | 714 | | #else | 715 | 0 | spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain; | 716 | 0 | if (tmp>.95) | 717 | 0 | tmp=.95; | 718 | 0 | #endif | 719 | 0 | gain_sum = gain_3tap_to_1tap(gain); | 720 | |
| 721 | 0 | if (gain_sum > tmp) | 722 | 0 | { | 723 | 0 | spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum); | 724 | 0 | for (i=0;i<3;i++) | 725 | 0 | gain[i]=MULT16_16_Q14(fact,gain[i]); | 726 | 0 | } | 727 | |
| 728 | 0 | } | 729 | |
| 730 | 0 | } | 731 | | | 732 | 60.3k | *pitch_val = pitch; | 733 | 60.3k | gain_val[0]=gain[0]; | 734 | 60.3k | gain_val[1]=gain[1]; | 735 | 60.3k | gain_val[2]=gain[2]; | 736 | 60.3k | gain[0] = SHL16(gain[0],7); | 737 | 60.3k | gain[1] = SHL16(gain[1],7); | 738 | 60.3k | gain[2] = SHL16(gain[2],7); | 739 | 60.3k | SPEEX_MEMSET(exc_out, 0, nsf); | 740 | 241k | for (i=0;i<3;i++) | 741 | 181k | { | 742 | 181k | int j; | 743 | 181k | int tmp1, tmp3; | 744 | 181k | int pp=pitch+1-i; | 745 | 181k | tmp1=nsf; | 746 | 181k | if (tmp1>pp) | 747 | 147k | tmp1=pp; | 748 | 4.14M | for (j=0;j<tmp1;j++) | 749 | 3.96M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); | 750 | 181k | tmp3=nsf; | 751 | 181k | if (tmp3>pp+pitch) | 752 | 136k | tmp3=pp+pitch; | 753 | 2.64M | for (j=tmp1;j<tmp3;j++) | 754 | 2.46M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); | 755 | 181k | } | 756 | | /*for (i=0;i<nsf;i++) | 757 | | exc[i]=PSHR32(exc32[i],13);*/ | 758 | 60.3k | } |
Line | Count | Source | 679 | 60.3k | { | 680 | 60.3k | int i; | 681 | 60.3k | int pitch; | 682 | 60.3k | int gain_index; | 683 | 60.3k | spx_word16_t gain[3]; | 684 | 60.3k | const signed char *gain_cdbk; | 685 | 60.3k | int gain_cdbk_size; | 686 | 60.3k | const ltp_params *params; | 687 | | | 688 | 60.3k | params = (const ltp_params*) par; | 689 | 60.3k | gain_cdbk_size = 1<<params->gain_bits; | 690 | 60.3k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 691 | | | 692 | 60.3k | pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); | 693 | 60.3k | pitch += start; | 694 | 60.3k | gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); | 695 | | /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ | 696 | 60.3k | #ifdef FIXED_POINT | 697 | 60.3k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); | 698 | 60.3k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); | 699 | 60.3k | gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+2]); | 700 | | #else | 701 | | gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5; | 702 | | gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5; | 703 | | gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5; | 704 | | #endif | 705 | | | 706 | 60.3k | if (count_lost && pitch > subframe_offset) | 707 | 0 | { | 708 | 0 | spx_word16_t gain_sum; | 709 | 0 | if (1) { | 710 | 0 | #ifdef FIXED_POINT | 711 | 0 | spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain,1); | 712 | 0 | if (tmp>62) | 713 | 0 | tmp=62; | 714 | | #else | 715 | | spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain; | 716 | | if (tmp>.95) | 717 | | tmp=.95; | 718 | | #endif | 719 | 0 | gain_sum = gain_3tap_to_1tap(gain); | 720 | |
| 721 | 0 | if (gain_sum > tmp) | 722 | 0 | { | 723 | 0 | spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum); | 724 | 0 | for (i=0;i<3;i++) | 725 | 0 | gain[i]=MULT16_16_Q14(fact,gain[i]); | 726 | 0 | } | 727 | |
| 728 | 0 | } | 729 | |
| 730 | 0 | } | 731 | | | 732 | 60.3k | *pitch_val = pitch; | 733 | 60.3k | gain_val[0]=gain[0]; | 734 | 60.3k | gain_val[1]=gain[1]; | 735 | 60.3k | gain_val[2]=gain[2]; | 736 | 60.3k | gain[0] = SHL16(gain[0],7); | 737 | 60.3k | gain[1] = SHL16(gain[1],7); | 738 | 60.3k | gain[2] = SHL16(gain[2],7); | 739 | 60.3k | SPEEX_MEMSET(exc_out, 0, nsf); | 740 | 241k | for (i=0;i<3;i++) | 741 | 181k | { | 742 | 181k | int j; | 743 | 181k | int tmp1, tmp3; | 744 | 181k | int pp=pitch+1-i; | 745 | 181k | tmp1=nsf; | 746 | 181k | if (tmp1>pp) | 747 | 147k | tmp1=pp; | 748 | 4.14M | for (j=0;j<tmp1;j++) | 749 | 3.96M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); | 750 | 181k | tmp3=nsf; | 751 | 181k | if (tmp3>pp+pitch) | 752 | 136k | tmp3=pp+pitch; | 753 | 2.64M | for (j=tmp1;j<tmp3;j++) | 754 | 2.46M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); | 755 | 181k | } | 756 | | /*for (i=0;i<nsf;i++) | 757 | | exc[i]=PSHR32(exc32[i],13);*/ | 758 | 60.3k | } |
|
759 | | #endif /* DISABLE_DECODER */ |
760 | | |
761 | | #ifndef DISABLE_ENCODER |
762 | | /** Forced pitch delay and gain */ |
763 | | int forced_pitch_quant( |
764 | | spx_word16_t target[], /* Target vector */ |
765 | | spx_word16_t *sw, |
766 | | spx_coef_t ak[], /* LPCs for this subframe */ |
767 | | spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ |
768 | | spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ |
769 | | spx_sig_t exc[], /* Excitation */ |
770 | | const void *par, |
771 | | int start, /* Smallest pitch value allowed */ |
772 | | int end, /* Largest pitch value allowed */ |
773 | | spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ |
774 | | int p, /* Number of LPC coeffs */ |
775 | | int nsf, /* Number of samples in subframe */ |
776 | | SpeexBits *bits, |
777 | | char *stack, |
778 | | spx_word16_t *exc2, |
779 | | spx_word16_t *r, |
780 | | int complexity, |
781 | | int cdbk_offset, |
782 | | int plc_tuning, |
783 | | spx_word32_t *cumul_gain |
784 | | ) |
785 | 55.6k | { |
786 | 55.6k | int i; |
787 | 55.6k | VARDECL(spx_word16_t *res); |
788 | 55.6k | ALLOC(res, nsf, spx_word16_t); |
789 | | #ifdef FIXED_POINT |
790 | 37.5k | if (pitch_coef>63) |
791 | 336 | pitch_coef=63; |
792 | | #else |
793 | 18.1k | if (pitch_coef>.99) |
794 | 144 | pitch_coef=.99; |
795 | | #endif |
796 | 1.73M | for (i=0;i<nsf&&i<start;i++) |
797 | 1.68M | { |
798 | 1.68M | exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); |
799 | 1.68M | } |
800 | 599k | for (;i<nsf;i++) |
801 | 543k | { |
802 | 543k | exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); |
803 | 543k | } |
804 | 2.28M | for (i=0;i<nsf;i++) |
805 | 2.22M | res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); |
806 | 55.6k | syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); |
807 | 2.28M | for (i=0;i<nsf;i++) |
808 | 2.22M | target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); |
809 | 55.6k | return start; |
810 | 55.6k | } Line | Count | Source | 785 | 18.1k | { | 786 | 18.1k | int i; | 787 | 18.1k | VARDECL(spx_word16_t *res); | 788 | 18.1k | ALLOC(res, nsf, spx_word16_t); | 789 | | #ifdef FIXED_POINT | 790 | | if (pitch_coef>63) | 791 | | pitch_coef=63; | 792 | | #else | 793 | 18.1k | if (pitch_coef>.99) | 794 | 144 | pitch_coef=.99; | 795 | 18.1k | #endif | 796 | 497k | for (i=0;i<nsf&&i<start;i++) | 797 | 479k | { | 798 | 479k | exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); | 799 | 479k | } | 800 | 262k | for (;i<nsf;i++) | 801 | 244k | { | 802 | 244k | exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); | 803 | 244k | } | 804 | 742k | for (i=0;i<nsf;i++) | 805 | 724k | res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); | 806 | 18.1k | syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); | 807 | 742k | for (i=0;i<nsf;i++) | 808 | 724k | target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); | 809 | 18.1k | return start; | 810 | 18.1k | } |
Line | Count | Source | 785 | 37.5k | { | 786 | 37.5k | int i; | 787 | 37.5k | VARDECL(spx_word16_t *res); | 788 | 37.5k | ALLOC(res, nsf, spx_word16_t); | 789 | 37.5k | #ifdef FIXED_POINT | 790 | 37.5k | if (pitch_coef>63) | 791 | 336 | pitch_coef=63; | 792 | | #else | 793 | | if (pitch_coef>.99) | 794 | | pitch_coef=.99; | 795 | | #endif | 796 | 1.24M | for (i=0;i<nsf&&i<start;i++) | 797 | 1.20M | { | 798 | 1.20M | exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); | 799 | 1.20M | } | 800 | 336k | for (;i<nsf;i++) | 801 | 299k | { | 802 | 299k | exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); | 803 | 299k | } | 804 | 1.54M | for (i=0;i<nsf;i++) | 805 | 1.50M | res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); | 806 | 37.5k | syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); | 807 | 1.54M | for (i=0;i<nsf;i++) | 808 | 1.50M | target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); | 809 | 37.5k | return start; | 810 | 37.5k | } |
|
811 | | #endif /* DISABLE_ENCODER */ |
812 | | |
813 | | #ifndef DISABLE_DECODER |
814 | | /** Unquantize forced pitch delay and gain */ |
815 | | void forced_pitch_unquant( |
816 | | spx_word16_t exc[], /* Input excitation */ |
817 | | spx_word32_t exc_out[], /* Output excitation */ |
818 | | int start, /* Smallest pitch value allowed */ |
819 | | int end, /* Largest pitch value allowed */ |
820 | | spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ |
821 | | const void *par, |
822 | | int nsf, /* Number of samples in subframe */ |
823 | | int *pitch_val, |
824 | | spx_word16_t *gain_val, |
825 | | SpeexBits *bits, |
826 | | char *stack, |
827 | | int count_lost, |
828 | | int subframe_offset, |
829 | | spx_word16_t last_pitch_gain, |
830 | | int cdbk_offset |
831 | | ) |
832 | 62.8k | { |
833 | 62.8k | int i; |
834 | | #ifdef FIXED_POINT |
835 | 31.4k | if (pitch_coef>63) |
836 | 4.04k | pitch_coef=63; |
837 | | #else |
838 | 31.4k | if (pitch_coef>.99) |
839 | 4.04k | pitch_coef=.99; |
840 | | #endif |
841 | 2.57M | for (i=0;i<nsf;i++) |
842 | 2.51M | { |
843 | 2.51M | exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); |
844 | 2.51M | exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); |
845 | 2.51M | } |
846 | 62.8k | *pitch_val = start; |
847 | 62.8k | gain_val[0]=gain_val[2]=0; |
848 | 62.8k | gain_val[1] = pitch_coef; |
849 | 62.8k | } Line | Count | Source | 832 | 31.4k | { | 833 | 31.4k | int i; | 834 | | #ifdef FIXED_POINT | 835 | | if (pitch_coef>63) | 836 | | pitch_coef=63; | 837 | | #else | 838 | 31.4k | if (pitch_coef>.99) | 839 | 4.04k | pitch_coef=.99; | 840 | 31.4k | #endif | 841 | 1.28M | for (i=0;i<nsf;i++) | 842 | 1.25M | { | 843 | 1.25M | exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); | 844 | 1.25M | exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); | 845 | 1.25M | } | 846 | 31.4k | *pitch_val = start; | 847 | 31.4k | gain_val[0]=gain_val[2]=0; | 848 | 31.4k | gain_val[1] = pitch_coef; | 849 | 31.4k | } |
Line | Count | Source | 832 | 31.4k | { | 833 | 31.4k | int i; | 834 | 31.4k | #ifdef FIXED_POINT | 835 | 31.4k | if (pitch_coef>63) | 836 | 4.04k | pitch_coef=63; | 837 | | #else | 838 | | if (pitch_coef>.99) | 839 | | pitch_coef=.99; | 840 | | #endif | 841 | 1.28M | for (i=0;i<nsf;i++) | 842 | 1.25M | { | 843 | 1.25M | exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); | 844 | 1.25M | exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); | 845 | 1.25M | } | 846 | 31.4k | *pitch_val = start; | 847 | 31.4k | gain_val[0]=gain_val[2]=0; | 848 | 31.4k | gain_val[1] = pitch_coef; | 849 | 31.4k | } |
|
850 | | #endif /* DISABLE_DECODER */ |