/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.58M | { |
60 | 6.58M | spx_word32_t sum=0; |
61 | 6.58M | len >>= 2; |
62 | 146M | while(len--) |
63 | 139M | { |
64 | 139M | spx_word32_t part=0; |
65 | 139M | part = MAC16_16(part,*x++,*y++); |
66 | 139M | part = MAC16_16(part,*x++,*y++); |
67 | 139M | part = MAC16_16(part,*x++,*y++); |
68 | 139M | part = MAC16_16(part,*x++,*y++); |
69 | | /* HINT: If you had a 40-bit accumulator, you could shift only at the end */ |
70 | 139M | sum = ADD32(sum,SHR32(part,6)); |
71 | 139M | } |
72 | 6.58M | return sum; |
73 | 6.58M | } |
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 | 40.3k | { |
145 | 40.3k | int i; |
146 | 4.93M | for (i=0;i<nb_pitch;i++) |
147 | 4.89M | { |
148 | | /* Compute correlation*/ |
149 | 4.89M | corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len); |
150 | 4.89M | } |
151 | | |
152 | 40.3k | } |
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 | 27.9M | { |
159 | 27.9M | spx_word32_t sum = 0; |
160 | 27.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); |
161 | 27.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); |
162 | 27.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); |
163 | 27.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); |
164 | 27.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); |
165 | 27.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); |
166 | 27.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); |
167 | 27.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); |
168 | 27.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); |
169 | 27.9M | return sum; |
170 | 27.9M | } ltp.c:compute_pitch_error Line | Count | Source | 158 | 13.9M | { | 159 | 13.9M | spx_word32_t sum = 0; | 160 | 13.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); | 161 | 13.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); | 162 | 13.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); | 163 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); | 164 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); | 165 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); | 166 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); | 167 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); | 168 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); | 169 | 13.9M | return sum; | 170 | 13.9M | } |
ltp.c:compute_pitch_error Line | Count | Source | 158 | 13.9M | { | 159 | 13.9M | spx_word32_t sum = 0; | 160 | 13.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[0],pitch_control),C[0])); | 161 | 13.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[1],pitch_control),C[1])); | 162 | 13.9M | sum = ADD32(sum,MULT16_16(MULT16_16_16(g[2],pitch_control),C[2])); | 163 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[1]),C[3])); | 164 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[1]),C[4])); | 165 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[0]),C[5])); | 166 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[0],g[0]),C[6])); | 167 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[1],g[1]),C[7])); | 168 | 13.9M | sum = SUB32(sum,MULT16_16(MULT16_16_16(g[2],g[2]),C[8])); | 169 | 13.9M | return sum; | 170 | 13.9M | } |
|
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 | 56.6k | { |
176 | 56.6k | int i,j,k; |
177 | 56.6k | VARDECL(spx_word32_t *best_score); |
178 | 56.6k | VARDECL(spx_word32_t *best_ener); |
179 | 56.6k | spx_word32_t e0; |
180 | 56.6k | 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 | 40.3k | ALLOC(corr16, end-start+1, spx_word16_t); |
190 | 40.3k | ALLOC(ener16, end-start+1, spx_word16_t); |
191 | 40.3k | 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.2k | ALLOC(energy, end-start+2, spx_word32_t); |
199 | 16.2k | ALLOC(corr, end-start+1, spx_word32_t); |
200 | | corr16 = corr; |
201 | | ener16 = energy; |
202 | | #endif |
203 | | |
204 | 56.6k | ALLOC(best_score, N, spx_word32_t); |
205 | 56.6k | ALLOC(best_ener, N, spx_word32_t); |
206 | 377k | for (i=0;i<N;i++) |
207 | 320k | { |
208 | 320k | best_score[i]=-1; |
209 | 320k | best_ener[i]=0; |
210 | 320k | pitch[i]=start; |
211 | 320k | } |
212 | | |
213 | | #ifdef FIXED_POINT |
214 | 7.55M | for (i=-end;i<len;i++) |
215 | 7.52M | { |
216 | 7.52M | if (ABS16(sw[i])>16383) |
217 | 11.3k | { |
218 | 11.3k | scaledown=1; |
219 | 11.3k | break; |
220 | 11.3k | } |
221 | 7.52M | } |
222 | | /* If the weighted input is close to saturation, then we scale it down */ |
223 | 40.3k | if (scaledown) |
224 | 11.3k | { |
225 | 2.64M | for (i=-end;i<len;i++) |
226 | 2.63M | { |
227 | 2.63M | sw[i]=SHR16(sw[i],1); |
228 | 2.63M | } |
229 | 11.3k | } |
230 | | #endif |
231 | 56.6k | energy[0]=inner_prod(sw-start, sw-start, len); |
232 | 56.6k | e0=inner_prod(sw, sw, len); |
233 | 6.86M | for (i=start;i<end;i++) |
234 | 6.80M | { |
235 | | /* Update energy for next pitch*/ |
236 | 6.80M | 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.80M | if (energy[i-start+1] < 0) |
238 | 6.79k | energy[i-start+1] = 0; |
239 | 6.80M | } |
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 | 56.6k | 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 | 40.3k | if (scaledown) |
253 | 11.3k | { |
254 | 2.64M | for (i=-end;i<len;i++) |
255 | 2.63M | { |
256 | 2.63M | sw[i]=SHL16(sw[i],1); |
257 | 2.63M | } |
258 | 11.3k | } |
259 | | #endif |
260 | | |
261 | | /* Search for the best pitch prediction gain */ |
262 | 6.91M | for (i=start;i<=end;i++) |
263 | 6.86M | { |
264 | 6.86M | 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.86M | if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) |
267 | 1.11M | { |
268 | | /* We can safely put it last and then check */ |
269 | 1.11M | best_score[N-1]=tmp; |
270 | 1.11M | best_ener[N-1]=ener16[i-start]+1; |
271 | 1.11M | pitch[N-1]=i; |
272 | | /* Check if it comes in front of others */ |
273 | 3.41M | for (j=0;j<N-1;j++) |
274 | 3.25M | { |
275 | 3.25M | if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) |
276 | 945k | { |
277 | 4.62M | for (k=N-1;k>j;k--) |
278 | 3.68M | { |
279 | 3.68M | best_score[k]=best_score[k-1]; |
280 | 3.68M | best_ener[k]=best_ener[k-1]; |
281 | 3.68M | pitch[k]=pitch[k-1]; |
282 | 3.68M | } |
283 | 945k | best_score[j]=tmp; |
284 | 945k | best_ener[j]=ener16[i-start]+1; |
285 | 945k | pitch[j]=i; |
286 | 945k | break; |
287 | 945k | } |
288 | 3.25M | } |
289 | 1.11M | } |
290 | 6.86M | } |
291 | | |
292 | | /* Compute open-loop gain if necessary */ |
293 | 56.6k | if (gain) |
294 | 25.8k | { |
295 | 181k | for (j=0;j<N;j++) |
296 | 155k | { |
297 | 155k | spx_word16_t g; |
298 | 155k | i=pitch[j]; |
299 | 155k | 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 | 155k | if (g<0) |
302 | 56.7k | g = 0; |
303 | 155k | gain[j]=g; |
304 | 155k | } |
305 | 25.8k | } |
306 | | |
307 | | |
308 | 56.6k | } Line | Count | Source | 175 | 16.2k | { | 176 | 16.2k | int i,j,k; | 177 | 16.2k | VARDECL(spx_word32_t *best_score); | 178 | 16.2k | VARDECL(spx_word32_t *best_ener); | 179 | 16.2k | spx_word32_t e0; | 180 | 16.2k | 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.2k | VARDECL(spx_word32_t *energy); | 196 | 16.2k | spx_word16_t *corr16; | 197 | 16.2k | spx_word16_t *ener16; | 198 | 16.2k | ALLOC(energy, end-start+2, spx_word32_t); | 199 | 16.2k | ALLOC(corr, end-start+1, spx_word32_t); | 200 | 16.2k | corr16 = corr; | 201 | 16.2k | ener16 = energy; | 202 | 16.2k | #endif | 203 | | | 204 | 16.2k | ALLOC(best_score, N, spx_word32_t); | 205 | 16.2k | ALLOC(best_ener, N, spx_word32_t); | 206 | 111k | for (i=0;i<N;i++) | 207 | 95.3k | { | 208 | 95.3k | best_score[i]=-1; | 209 | 95.3k | best_ener[i]=0; | 210 | 95.3k | pitch[i]=start; | 211 | 95.3k | } | 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.2k | energy[0]=inner_prod(sw-start, sw-start, len); | 232 | 16.2k | e0=inner_prod(sw, sw, len); | 233 | 1.96M | for (i=start;i<end;i++) | 234 | 1.94M | { | 235 | | /* Update energy for next pitch*/ | 236 | 1.94M | 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.94M | if (energy[i-start+1] < 0) | 238 | 6.79k | energy[i-start+1] = 0; | 239 | 1.94M | } | 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.2k | 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.98M | for (i=start;i<=end;i++) | 263 | 1.96M | { | 264 | 1.96M | 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.96M | if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) | 267 | 352k | { | 268 | | /* We can safely put it last and then check */ | 269 | 352k | best_score[N-1]=tmp; | 270 | 352k | best_ener[N-1]=ener16[i-start]+1; | 271 | 352k | pitch[N-1]=i; | 272 | | /* Check if it comes in front of others */ | 273 | 949k | for (j=0;j<N-1;j++) | 274 | 904k | { | 275 | 904k | if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) | 276 | 307k | { | 277 | 1.67M | for (k=N-1;k>j;k--) | 278 | 1.36M | { | 279 | 1.36M | best_score[k]=best_score[k-1]; | 280 | 1.36M | best_ener[k]=best_ener[k-1]; | 281 | 1.36M | pitch[k]=pitch[k-1]; | 282 | 1.36M | } | 283 | 307k | best_score[j]=tmp; | 284 | 307k | best_ener[j]=ener16[i-start]+1; | 285 | 307k | pitch[j]=i; | 286 | 307k | break; | 287 | 307k | } | 288 | 904k | } | 289 | 352k | } | 290 | 1.96M | } | 291 | | | 292 | | /* Compute open-loop gain if necessary */ | 293 | 16.2k | if (gain) | 294 | 7.90k | { | 295 | 55.3k | for (j=0;j<N;j++) | 296 | 47.4k | { | 297 | 47.4k | spx_word16_t g; | 298 | 47.4k | i=pitch[j]; | 299 | 47.4k | 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 | 47.4k | if (g<0) | 302 | 13.9k | g = 0; | 303 | 47.4k | gain[j]=g; | 304 | 47.4k | } | 305 | 7.90k | } | 306 | | | 307 | | | 308 | 16.2k | } |
Line | Count | Source | 175 | 40.3k | { | 176 | 40.3k | int i,j,k; | 177 | 40.3k | VARDECL(spx_word32_t *best_score); | 178 | 40.3k | VARDECL(spx_word32_t *best_ener); | 179 | 40.3k | spx_word32_t e0; | 180 | 40.3k | VARDECL(spx_word32_t *corr); | 181 | 40.3k | #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 | 40.3k | VARDECL(spx_word16_t *corr16); | 185 | 40.3k | VARDECL(spx_word16_t *ener16); | 186 | 40.3k | spx_word32_t *energy; | 187 | 40.3k | int cshift=0, eshift=0; | 188 | 40.3k | int scaledown = 0; | 189 | 40.3k | ALLOC(corr16, end-start+1, spx_word16_t); | 190 | 40.3k | ALLOC(ener16, end-start+1, spx_word16_t); | 191 | 40.3k | ALLOC(corr, end-start+1, spx_word32_t); | 192 | 40.3k | 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 | 40.3k | ALLOC(best_score, N, spx_word32_t); | 205 | 40.3k | ALLOC(best_ener, N, spx_word32_t); | 206 | 265k | for (i=0;i<N;i++) | 207 | 225k | { | 208 | 225k | best_score[i]=-1; | 209 | 225k | best_ener[i]=0; | 210 | 225k | pitch[i]=start; | 211 | 225k | } | 212 | | | 213 | 40.3k | #ifdef FIXED_POINT | 214 | 7.55M | for (i=-end;i<len;i++) | 215 | 7.52M | { | 216 | 7.52M | if (ABS16(sw[i])>16383) | 217 | 11.3k | { | 218 | 11.3k | scaledown=1; | 219 | 11.3k | break; | 220 | 11.3k | } | 221 | 7.52M | } | 222 | | /* If the weighted input is close to saturation, then we scale it down */ | 223 | 40.3k | if (scaledown) | 224 | 11.3k | { | 225 | 2.64M | for (i=-end;i<len;i++) | 226 | 2.63M | { | 227 | 2.63M | sw[i]=SHR16(sw[i],1); | 228 | 2.63M | } | 229 | 11.3k | } | 230 | 40.3k | #endif | 231 | 40.3k | energy[0]=inner_prod(sw-start, sw-start, len); | 232 | 40.3k | e0=inner_prod(sw, sw, len); | 233 | 4.89M | for (i=start;i<end;i++) | 234 | 4.85M | { | 235 | | /* Update energy for next pitch*/ | 236 | 4.85M | 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.85M | if (energy[i-start+1] < 0) | 238 | 0 | energy[i-start+1] = 0; | 239 | 4.85M | } | 240 | | | 241 | 40.3k | #ifdef FIXED_POINT | 242 | 40.3k | eshift = normalize16(energy, ener16, 32766, end-start+1); | 243 | 40.3k | #endif | 244 | | | 245 | | /* In fixed-point, this actually overrites the energy array (aliased to corr) */ | 246 | 40.3k | pitch_xcorr(sw, sw-end, corr, len, end-start+1, stack); | 247 | | | 248 | 40.3k | #ifdef FIXED_POINT | 249 | | /* Normalize to 180 so we can square it and it still fits in 16 bits */ | 250 | 40.3k | 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 | 40.3k | if (scaledown) | 253 | 11.3k | { | 254 | 2.64M | for (i=-end;i<len;i++) | 255 | 2.63M | { | 256 | 2.63M | sw[i]=SHL16(sw[i],1); | 257 | 2.63M | } | 258 | 11.3k | } | 259 | 40.3k | #endif | 260 | | | 261 | | /* Search for the best pitch prediction gain */ | 262 | 4.93M | for (i=start;i<=end;i++) | 263 | 4.89M | { | 264 | 4.89M | 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.89M | if (MULT16_16(tmp,best_ener[N-1])>MULT16_16(best_score[N-1],ADD16(1,ener16[i-start]))) | 267 | 758k | { | 268 | | /* We can safely put it last and then check */ | 269 | 758k | best_score[N-1]=tmp; | 270 | 758k | best_ener[N-1]=ener16[i-start]+1; | 271 | 758k | pitch[N-1]=i; | 272 | | /* Check if it comes in front of others */ | 273 | 2.46M | for (j=0;j<N-1;j++) | 274 | 2.34M | { | 275 | 2.34M | if (MULT16_16(tmp,best_ener[j])>MULT16_16(best_score[j],ADD16(1,ener16[i-start]))) | 276 | 637k | { | 277 | 2.95M | for (k=N-1;k>j;k--) | 278 | 2.31M | { | 279 | 2.31M | best_score[k]=best_score[k-1]; | 280 | 2.31M | best_ener[k]=best_ener[k-1]; | 281 | 2.31M | pitch[k]=pitch[k-1]; | 282 | 2.31M | } | 283 | 637k | best_score[j]=tmp; | 284 | 637k | best_ener[j]=ener16[i-start]+1; | 285 | 637k | pitch[j]=i; | 286 | 637k | break; | 287 | 637k | } | 288 | 2.34M | } | 289 | 758k | } | 290 | 4.89M | } | 291 | | | 292 | | /* Compute open-loop gain if necessary */ | 293 | 40.3k | if (gain) | 294 | 17.9k | { | 295 | 125k | for (j=0;j<N;j++) | 296 | 107k | { | 297 | 107k | spx_word16_t g; | 298 | 107k | i=pitch[j]; | 299 | 107k | 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 | 107k | if (g<0) | 302 | 42.7k | g = 0; | 303 | 107k | gain[j]=g; | 304 | 107k | } | 305 | 17.9k | } | 306 | | | 307 | | | 308 | 40.3k | } |
|
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 | 342k | { |
319 | 342k | const signed char *ptr=gain_cdbk; |
320 | 342k | int best_cdbk=0; |
321 | 342k | spx_word32_t best_sum=-VERY_LARGE32; |
322 | 342k | spx_word32_t sum=0; |
323 | 342k | spx_word16_t g[3]; |
324 | 342k | spx_word16_t pitch_control=64; |
325 | 342k | spx_word16_t gain_sum; |
326 | 342k | int i; |
327 | | |
328 | 28.2M | for (i=0;i<gain_cdbk_size;i++) { |
329 | | |
330 | 27.9M | ptr = gain_cdbk+4*i; |
331 | 27.9M | g[0]=ADD16((spx_word16_t)ptr[0],32); |
332 | 27.9M | g[1]=ADD16((spx_word16_t)ptr[1],32); |
333 | 27.9M | g[2]=ADD16((spx_word16_t)ptr[2],32); |
334 | 27.9M | gain_sum = (spx_word16_t)ptr[3]; |
335 | | |
336 | 27.9M | sum = compute_pitch_error(C16, g, pitch_control); |
337 | | |
338 | 27.9M | if (sum>best_sum && gain_sum<=max_gain) { |
339 | 1.04M | best_sum=sum; |
340 | 1.04M | best_cdbk=i; |
341 | 1.04M | } |
342 | 27.9M | } |
343 | | |
344 | 342k | return best_cdbk; |
345 | 342k | } ltp.c:pitch_gain_search_3tap_vq Line | Count | Source | 318 | 171k | { | 319 | 171k | const signed char *ptr=gain_cdbk; | 320 | 171k | int best_cdbk=0; | 321 | 171k | spx_word32_t best_sum=-VERY_LARGE32; | 322 | 171k | spx_word32_t sum=0; | 323 | 171k | spx_word16_t g[3]; | 324 | 171k | spx_word16_t pitch_control=64; | 325 | 171k | spx_word16_t gain_sum; | 326 | 171k | int i; | 327 | | | 328 | 14.1M | for (i=0;i<gain_cdbk_size;i++) { | 329 | | | 330 | 13.9M | ptr = gain_cdbk+4*i; | 331 | 13.9M | g[0]=ADD16((spx_word16_t)ptr[0],32); | 332 | 13.9M | g[1]=ADD16((spx_word16_t)ptr[1],32); | 333 | 13.9M | g[2]=ADD16((spx_word16_t)ptr[2],32); | 334 | 13.9M | gain_sum = (spx_word16_t)ptr[3]; | 335 | | | 336 | 13.9M | sum = compute_pitch_error(C16, g, pitch_control); | 337 | | | 338 | 13.9M | if (sum>best_sum && gain_sum<=max_gain) { | 339 | 522k | best_sum=sum; | 340 | 522k | best_cdbk=i; | 341 | 522k | } | 342 | 13.9M | } | 343 | | | 344 | 171k | return best_cdbk; | 345 | 171k | } |
ltp.c:pitch_gain_search_3tap_vq Line | Count | Source | 318 | 171k | { | 319 | 171k | const signed char *ptr=gain_cdbk; | 320 | 171k | int best_cdbk=0; | 321 | 171k | spx_word32_t best_sum=-VERY_LARGE32; | 322 | 171k | spx_word32_t sum=0; | 323 | 171k | spx_word16_t g[3]; | 324 | 171k | spx_word16_t pitch_control=64; | 325 | 171k | spx_word16_t gain_sum; | 326 | 171k | int i; | 327 | | | 328 | 14.1M | for (i=0;i<gain_cdbk_size;i++) { | 329 | | | 330 | 13.9M | ptr = gain_cdbk+4*i; | 331 | 13.9M | g[0]=ADD16((spx_word16_t)ptr[0],32); | 332 | 13.9M | g[1]=ADD16((spx_word16_t)ptr[1],32); | 333 | 13.9M | g[2]=ADD16((spx_word16_t)ptr[2],32); | 334 | 13.9M | gain_sum = (spx_word16_t)ptr[3]; | 335 | | | 336 | 13.9M | sum = compute_pitch_error(C16, g, pitch_control); | 337 | | | 338 | 13.9M | if (sum>best_sum && gain_sum<=max_gain) { | 339 | 522k | best_sum=sum; | 340 | 522k | best_cdbk=i; | 341 | 522k | } | 342 | 13.9M | } | 343 | | | 344 | 171k | return best_cdbk; | 345 | 171k | } |
|
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 | 171k | { |
371 | 171k | int i,j; |
372 | 171k | VARDECL(spx_word16_t *tmp1); |
373 | 171k | VARDECL(spx_word16_t *e); |
374 | 171k | spx_word16_t *x[3]; |
375 | 171k | spx_word32_t corr[3]; |
376 | 171k | spx_word32_t A[3][3]; |
377 | 171k | spx_word16_t gain[3]; |
378 | 171k | spx_word32_t err; |
379 | 171k | spx_word16_t max_gain=128; |
380 | 171k | int best_cdbk=0; |
381 | | |
382 | 171k | ALLOC(tmp1, 3*nsf, spx_word16_t); |
383 | 171k | ALLOC(e, nsf, spx_word16_t); |
384 | | |
385 | 171k | if (cumul_gain > 262144) |
386 | 694 | max_gain = 31; |
387 | | |
388 | 171k | x[0]=tmp1; |
389 | 171k | x[1]=tmp1+nsf; |
390 | 171k | x[2]=tmp1+2*nsf; |
391 | | |
392 | 7.01M | for (j=0;j<nsf;j++) |
393 | 6.84M | new_target[j] = target[j]; |
394 | | |
395 | 171k | { |
396 | 171k | int bound; |
397 | 171k | VARDECL(spx_mem_t *mm); |
398 | 171k | int pp=pitch-1; |
399 | 171k | ALLOC(mm, p, spx_mem_t); |
400 | 171k | bound = nsf; |
401 | 171k | if (nsf-pp>0) |
402 | 70.0k | bound = pp; |
403 | 5.91M | for (j=0;j<bound;j++) |
404 | 5.74M | e[j]=exc2[j-pp]; |
405 | 171k | bound = nsf; |
406 | 171k | if (nsf-pp-pitch>0) |
407 | 23.7k | bound = pp+pitch; |
408 | 1.17M | for (;j<bound;j++) |
409 | 1.00M | e[j]=exc2[j-pp-pitch]; |
410 | 274k | for (;j<nsf;j++) |
411 | 103k | e[j]=0; |
412 | | #ifdef FIXED_POINT |
413 | | /* Scale target and excitation down if needed (avoiding overflow) */ |
414 | 122k | if (scaledown) |
415 | 28.6k | { |
416 | 1.17M | for (j=0;j<nsf;j++) |
417 | 1.14M | e[j] = SHR16(e[j],1); |
418 | 1.17M | for (j=0;j<nsf;j++) |
419 | 1.14M | new_target[j] = SHR16(new_target[j],1); |
420 | 28.6k | } |
421 | | #endif |
422 | 1.88M | for (j=0;j<p;j++) |
423 | 1.71M | mm[j] = 0; |
424 | 171k | iir_mem16(e, ak, e, nsf, p, mm, stack); |
425 | 1.88M | for (j=0;j<p;j++) |
426 | 1.71M | mm[j] = 0; |
427 | 171k | filter10(e, awk1, awk2, e, nsf, mm, stack); |
428 | 7.01M | for (j=0;j<nsf;j++) |
429 | 6.84M | x[2][j] = e[j]; |
430 | 171k | } |
431 | 513k | for (i=1;i>=0;i--) |
432 | 342k | { |
433 | 342k | spx_word16_t e0=exc2[-pitch-1+i]; |
434 | | #ifdef FIXED_POINT |
435 | | /* Scale excitation down if needed (avoiding overflow) */ |
436 | 244k | if (scaledown) |
437 | 57.2k | e0 = SHR16(e0,1); |
438 | | #endif |
439 | 342k | x[i][0]=MULT16_16_Q14(r[0], e0); |
440 | 13.6M | for (j=0;j<nsf-1;j++) |
441 | 13.3M | x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); |
442 | 342k | } |
443 | | |
444 | 684k | for (i=0;i<3;i++) |
445 | 513k | corr[i]=inner_prod(x[i],new_target,nsf); |
446 | 684k | for (i=0;i<3;i++) |
447 | 1.54M | for (j=0;j<=i;j++) |
448 | 1.02M | A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); |
449 | | |
450 | 171k | { |
451 | 171k | 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 | 171k | C[0]=corr[2]; |
458 | 171k | C[1]=corr[1]; |
459 | 171k | C[2]=corr[0]; |
460 | 171k | C[3]=A[1][2]; |
461 | 171k | C[4]=A[0][1]; |
462 | 171k | C[5]=A[0][2]; |
463 | 171k | C[6]=A[2][2]; |
464 | 171k | C[7]=A[1][1]; |
465 | 171k | C[8]=A[0][0]; |
466 | | |
467 | | /*plc_tuning *= 2;*/ |
468 | 171k | if (plc_tuning<2) |
469 | 0 | plc_tuning=2; |
470 | 171k | if (plc_tuning>30) |
471 | 0 | plc_tuning=30; |
472 | | #ifdef FIXED_POINT |
473 | 122k | C[0] = SHL32(C[0],1); |
474 | 122k | C[1] = SHL32(C[1],1); |
475 | 122k | C[2] = SHL32(C[2],1); |
476 | 122k | C[3] = SHL32(C[3],1); |
477 | 122k | C[4] = SHL32(C[4],1); |
478 | 122k | C[5] = SHL32(C[5],1); |
479 | 122k | C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); |
480 | 122k | C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); |
481 | 122k | 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 | 171k | best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); |
490 | | |
491 | | #ifdef FIXED_POINT |
492 | 122k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); |
493 | 122k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); |
494 | 122k | 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 | 171k | *cdbk_index=best_cdbk; |
502 | 171k | } |
503 | | |
504 | 171k | SPEEX_MEMSET(exc, 0, nsf); |
505 | 684k | for (i=0;i<3;i++) |
506 | 513k | { |
507 | 513k | int j; |
508 | 513k | int tmp1, tmp3; |
509 | 513k | int pp=pitch+1-i; |
510 | 513k | tmp1=nsf; |
511 | 513k | if (tmp1>pp) |
512 | 203k | tmp1=pp; |
513 | 17.9M | for (j=0;j<tmp1;j++) |
514 | 17.4M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); |
515 | 513k | tmp3=nsf; |
516 | 513k | if (tmp3>pp+pitch) |
517 | 61.0k | tmp3=pp+pitch; |
518 | 3.37M | for (j=tmp1;j<tmp3;j++) |
519 | 2.86M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); |
520 | 513k | } |
521 | 7.01M | for (i=0;i<nsf;i++) |
522 | 6.84M | { |
523 | 6.84M | spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), |
524 | 6.84M | MULT16_16(gain[2],x[0][i])); |
525 | 6.84M | new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); |
526 | 6.84M | } |
527 | 171k | err = inner_prod(new_target, new_target, nsf); |
528 | | |
529 | 171k | return err; |
530 | 171k | } ltp.c:pitch_gain_search_3tap Line | Count | Source | 370 | 49.1k | { | 371 | 49.1k | int i,j; | 372 | 49.1k | VARDECL(spx_word16_t *tmp1); | 373 | 49.1k | VARDECL(spx_word16_t *e); | 374 | 49.1k | spx_word16_t *x[3]; | 375 | 49.1k | spx_word32_t corr[3]; | 376 | 49.1k | spx_word32_t A[3][3]; | 377 | 49.1k | spx_word16_t gain[3]; | 378 | 49.1k | spx_word32_t err; | 379 | 49.1k | spx_word16_t max_gain=128; | 380 | 49.1k | int best_cdbk=0; | 381 | | | 382 | 49.1k | ALLOC(tmp1, 3*nsf, spx_word16_t); | 383 | 49.1k | ALLOC(e, nsf, spx_word16_t); | 384 | | | 385 | 49.1k | if (cumul_gain > 262144) | 386 | 330 | max_gain = 31; | 387 | | | 388 | 49.1k | x[0]=tmp1; | 389 | 49.1k | x[1]=tmp1+nsf; | 390 | 49.1k | x[2]=tmp1+2*nsf; | 391 | | | 392 | 2.01M | for (j=0;j<nsf;j++) | 393 | 1.96M | new_target[j] = target[j]; | 394 | | | 395 | 49.1k | { | 396 | 49.1k | int bound; | 397 | 49.1k | VARDECL(spx_mem_t *mm); | 398 | 49.1k | int pp=pitch-1; | 399 | 49.1k | ALLOC(mm, p, spx_mem_t); | 400 | 49.1k | bound = nsf; | 401 | 49.1k | if (nsf-pp>0) | 402 | 23.8k | bound = pp; | 403 | 1.62M | for (j=0;j<bound;j++) | 404 | 1.57M | e[j]=exc2[j-pp]; | 405 | 49.1k | bound = nsf; | 406 | 49.1k | if (nsf-pp-pitch>0) | 407 | 8.20k | bound = pp+pitch; | 408 | 399k | for (;j<bound;j++) | 409 | 350k | e[j]=exc2[j-pp-pitch]; | 410 | 87.1k | for (;j<nsf;j++) | 411 | 38.0k | 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 | 540k | for (j=0;j<p;j++) | 423 | 491k | mm[j] = 0; | 424 | 49.1k | iir_mem16(e, ak, e, nsf, p, mm, stack); | 425 | 540k | for (j=0;j<p;j++) | 426 | 491k | mm[j] = 0; | 427 | 49.1k | filter10(e, awk1, awk2, e, nsf, mm, stack); | 428 | 2.01M | for (j=0;j<nsf;j++) | 429 | 1.96M | x[2][j] = e[j]; | 430 | 49.1k | } | 431 | 147k | for (i=1;i>=0;i--) | 432 | 98.2k | { | 433 | 98.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 | 98.2k | x[i][0]=MULT16_16_Q14(r[0], e0); | 440 | 3.93M | for (j=0;j<nsf-1;j++) | 441 | 3.83M | x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); | 442 | 98.2k | } | 443 | | | 444 | 196k | for (i=0;i<3;i++) | 445 | 147k | corr[i]=inner_prod(x[i],new_target,nsf); | 446 | 196k | for (i=0;i<3;i++) | 447 | 442k | for (j=0;j<=i;j++) | 448 | 294k | A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); | 449 | | | 450 | 49.1k | { | 451 | 49.1k | spx_word32_t C[9]; | 452 | | #ifdef FIXED_POINT | 453 | | spx_word16_t C16[9]; | 454 | | #else | 455 | 49.1k | spx_word16_t *C16=C; | 456 | 49.1k | #endif | 457 | 49.1k | C[0]=corr[2]; | 458 | 49.1k | C[1]=corr[1]; | 459 | 49.1k | C[2]=corr[0]; | 460 | 49.1k | C[3]=A[1][2]; | 461 | 49.1k | C[4]=A[0][1]; | 462 | 49.1k | C[5]=A[0][2]; | 463 | 49.1k | C[6]=A[2][2]; | 464 | 49.1k | C[7]=A[1][1]; | 465 | 49.1k | C[8]=A[0][0]; | 466 | | | 467 | | /*plc_tuning *= 2;*/ | 468 | 49.1k | if (plc_tuning<2) | 469 | 0 | plc_tuning=2; | 470 | 49.1k | 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.1k | C[6]*=.5*(1+.02*plc_tuning); | 485 | 49.1k | C[7]*=.5*(1+.02*plc_tuning); | 486 | 49.1k | C[8]*=.5*(1+.02*plc_tuning); | 487 | 49.1k | #endif | 488 | | | 489 | 49.1k | 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.1k | gain[0] = 0.015625*gain_cdbk[best_cdbk*4] + .5; | 498 | 49.1k | gain[1] = 0.015625*gain_cdbk[best_cdbk*4+1]+ .5; | 499 | 49.1k | gain[2] = 0.015625*gain_cdbk[best_cdbk*4+2]+ .5; | 500 | 49.1k | #endif | 501 | 49.1k | *cdbk_index=best_cdbk; | 502 | 49.1k | } | 503 | | | 504 | 49.1k | SPEEX_MEMSET(exc, 0, nsf); | 505 | 196k | for (i=0;i<3;i++) | 506 | 147k | { | 507 | 147k | int j; | 508 | 147k | int tmp1, tmp3; | 509 | 147k | int pp=pitch+1-i; | 510 | 147k | tmp1=nsf; | 511 | 147k | if (tmp1>pp) | 512 | 70.4k | tmp1=pp; | 513 | 4.95M | for (j=0;j<tmp1;j++) | 514 | 4.80M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); | 515 | 147k | tmp3=nsf; | 516 | 147k | if (tmp3>pp+pitch) | 517 | 21.9k | tmp3=pp+pitch; | 518 | 1.15M | for (j=tmp1;j<tmp3;j++) | 519 | 1.00M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); | 520 | 147k | } | 521 | 2.01M | for (i=0;i<nsf;i++) | 522 | 1.96M | { | 523 | 1.96M | spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), | 524 | 1.96M | MULT16_16(gain[2],x[0][i])); | 525 | 1.96M | new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); | 526 | 1.96M | } | 527 | 49.1k | err = inner_prod(new_target, new_target, nsf); | 528 | | | 529 | 49.1k | return err; | 530 | 49.1k | } |
ltp.c:pitch_gain_search_3tap Line | Count | Source | 370 | 122k | { | 371 | 122k | int i,j; | 372 | 122k | VARDECL(spx_word16_t *tmp1); | 373 | 122k | VARDECL(spx_word16_t *e); | 374 | 122k | spx_word16_t *x[3]; | 375 | 122k | spx_word32_t corr[3]; | 376 | 122k | spx_word32_t A[3][3]; | 377 | 122k | spx_word16_t gain[3]; | 378 | 122k | spx_word32_t err; | 379 | 122k | spx_word16_t max_gain=128; | 380 | 122k | int best_cdbk=0; | 381 | | | 382 | 122k | ALLOC(tmp1, 3*nsf, spx_word16_t); | 383 | 122k | ALLOC(e, nsf, spx_word16_t); | 384 | | | 385 | 122k | if (cumul_gain > 262144) | 386 | 364 | max_gain = 31; | 387 | | | 388 | 122k | x[0]=tmp1; | 389 | 122k | x[1]=tmp1+nsf; | 390 | 122k | x[2]=tmp1+2*nsf; | 391 | | | 392 | 5.00M | for (j=0;j<nsf;j++) | 393 | 4.88M | new_target[j] = target[j]; | 394 | | | 395 | 122k | { | 396 | 122k | int bound; | 397 | 122k | VARDECL(spx_mem_t *mm); | 398 | 122k | int pp=pitch-1; | 399 | 122k | ALLOC(mm, p, spx_mem_t); | 400 | 122k | bound = nsf; | 401 | 122k | if (nsf-pp>0) | 402 | 46.2k | bound = pp; | 403 | 4.28M | for (j=0;j<bound;j++) | 404 | 4.16M | e[j]=exc2[j-pp]; | 405 | 122k | bound = nsf; | 406 | 122k | if (nsf-pp-pitch>0) | 407 | 15.5k | bound = pp+pitch; | 408 | 772k | for (;j<bound;j++) | 409 | 650k | e[j]=exc2[j-pp-pitch]; | 410 | 187k | for (;j<nsf;j++) | 411 | 65.0k | e[j]=0; | 412 | 122k | #ifdef FIXED_POINT | 413 | | /* Scale target and excitation down if needed (avoiding overflow) */ | 414 | 122k | if (scaledown) | 415 | 28.6k | { | 416 | 1.17M | for (j=0;j<nsf;j++) | 417 | 1.14M | e[j] = SHR16(e[j],1); | 418 | 1.17M | for (j=0;j<nsf;j++) | 419 | 1.14M | new_target[j] = SHR16(new_target[j],1); | 420 | 28.6k | } | 421 | 122k | #endif | 422 | 1.34M | for (j=0;j<p;j++) | 423 | 1.22M | mm[j] = 0; | 424 | 122k | iir_mem16(e, ak, e, nsf, p, mm, stack); | 425 | 1.34M | for (j=0;j<p;j++) | 426 | 1.22M | mm[j] = 0; | 427 | 122k | filter10(e, awk1, awk2, e, nsf, mm, stack); | 428 | 5.00M | for (j=0;j<nsf;j++) | 429 | 4.88M | x[2][j] = e[j]; | 430 | 122k | } | 431 | 366k | for (i=1;i>=0;i--) | 432 | 244k | { | 433 | 244k | spx_word16_t e0=exc2[-pitch-1+i]; | 434 | 244k | #ifdef FIXED_POINT | 435 | | /* Scale excitation down if needed (avoiding overflow) */ | 436 | 244k | if (scaledown) | 437 | 57.2k | e0 = SHR16(e0,1); | 438 | 244k | #endif | 439 | 244k | x[i][0]=MULT16_16_Q14(r[0], e0); | 440 | 9.76M | for (j=0;j<nsf-1;j++) | 441 | 9.52M | x[i][j+1]=ADD32(x[i+1][j],MULT16_16_P14(r[j+1], e0)); | 442 | 244k | } | 443 | | | 444 | 488k | for (i=0;i<3;i++) | 445 | 366k | corr[i]=inner_prod(x[i],new_target,nsf); | 446 | 488k | for (i=0;i<3;i++) | 447 | 1.09M | for (j=0;j<=i;j++) | 448 | 732k | A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf); | 449 | | | 450 | 122k | { | 451 | 122k | spx_word32_t C[9]; | 452 | 122k | #ifdef FIXED_POINT | 453 | 122k | spx_word16_t C16[9]; | 454 | | #else | 455 | | spx_word16_t *C16=C; | 456 | | #endif | 457 | 122k | C[0]=corr[2]; | 458 | 122k | C[1]=corr[1]; | 459 | 122k | C[2]=corr[0]; | 460 | 122k | C[3]=A[1][2]; | 461 | 122k | C[4]=A[0][1]; | 462 | 122k | C[5]=A[0][2]; | 463 | 122k | C[6]=A[2][2]; | 464 | 122k | C[7]=A[1][1]; | 465 | 122k | C[8]=A[0][0]; | 466 | | | 467 | | /*plc_tuning *= 2;*/ | 468 | 122k | if (plc_tuning<2) | 469 | 0 | plc_tuning=2; | 470 | 122k | if (plc_tuning>30) | 471 | 0 | plc_tuning=30; | 472 | 122k | #ifdef FIXED_POINT | 473 | 122k | C[0] = SHL32(C[0],1); | 474 | 122k | C[1] = SHL32(C[1],1); | 475 | 122k | C[2] = SHL32(C[2],1); | 476 | 122k | C[3] = SHL32(C[3],1); | 477 | 122k | C[4] = SHL32(C[4],1); | 478 | 122k | C[5] = SHL32(C[5],1); | 479 | 122k | C[6] = MAC16_32_Q15(C[6],MULT16_16_16(plc_tuning,655),C[6]); | 480 | 122k | C[7] = MAC16_32_Q15(C[7],MULT16_16_16(plc_tuning,655),C[7]); | 481 | 122k | C[8] = MAC16_32_Q15(C[8],MULT16_16_16(plc_tuning,655),C[8]); | 482 | 122k | 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 | 122k | best_cdbk = pitch_gain_search_3tap_vq(gain_cdbk, gain_cdbk_size, C16, max_gain); | 490 | | | 491 | 122k | #ifdef FIXED_POINT | 492 | 122k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4]); | 493 | 122k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*4+1]); | 494 | 122k | 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 | 122k | *cdbk_index=best_cdbk; | 502 | 122k | } | 503 | | | 504 | 122k | SPEEX_MEMSET(exc, 0, nsf); | 505 | 488k | for (i=0;i<3;i++) | 506 | 366k | { | 507 | 366k | int j; | 508 | 366k | int tmp1, tmp3; | 509 | 366k | int pp=pitch+1-i; | 510 | 366k | tmp1=nsf; | 511 | 366k | if (tmp1>pp) | 512 | 133k | tmp1=pp; | 513 | 13.0M | for (j=0;j<tmp1;j++) | 514 | 12.6M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp]); | 515 | 366k | tmp3=nsf; | 516 | 366k | if (tmp3>pp+pitch) | 517 | 39.1k | tmp3=pp+pitch; | 518 | 2.22M | for (j=tmp1;j<tmp3;j++) | 519 | 1.85M | exc[j]=MAC16_16(exc[j],SHL16(gain[2-i],7),exc2[j-pp-pitch]); | 520 | 366k | } | 521 | 5.00M | for (i=0;i<nsf;i++) | 522 | 4.88M | { | 523 | 4.88M | spx_word32_t tmp = ADD32(ADD32(MULT16_16(gain[0],x[2][i]),MULT16_16(gain[1],x[1][i])), | 524 | 4.88M | MULT16_16(gain[2],x[0][i])); | 525 | 4.88M | new_target[i] = SUB16(new_target[i], EXTRACT16(PSHR32(tmp,6))); | 526 | 4.88M | } | 527 | 122k | err = inner_prod(new_target, new_target, nsf); | 528 | | | 529 | 122k | return err; | 530 | 122k | } |
|
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 | 38.5k | { |
556 | 38.5k | int i; |
557 | 38.5k | int cdbk_index, pitch=0, best_gain_index=0; |
558 | 38.5k | VARDECL(spx_sig_t *best_exc); |
559 | 38.5k | VARDECL(spx_word16_t *new_target); |
560 | 38.5k | VARDECL(spx_word16_t *best_target); |
561 | 38.5k | int best_pitch=0; |
562 | 38.5k | spx_word32_t err, best_err=-1; |
563 | 38.5k | int N; |
564 | 38.5k | const ltp_params *params; |
565 | 38.5k | const signed char *gain_cdbk; |
566 | 38.5k | int gain_cdbk_size; |
567 | 38.5k | int scaledown=0; |
568 | | |
569 | 38.5k | VARDECL(int *nbest); |
570 | | |
571 | 38.5k | params = (const ltp_params*) par; |
572 | 38.5k | gain_cdbk_size = 1<<params->gain_bits; |
573 | 38.5k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; |
574 | | |
575 | 38.5k | N=complexity; |
576 | 38.5k | if (N>10) |
577 | 0 | N=10; |
578 | 38.5k | if (N<1) |
579 | 5.99k | N=1; |
580 | | |
581 | 38.5k | ALLOC(nbest, N, int); |
582 | 38.5k | params = (const ltp_params*) par; |
583 | | |
584 | 38.5k | if (end<start) |
585 | 2.33k | { |
586 | 2.33k | speex_bits_pack(bits, 0, params->pitch_bits); |
587 | 2.33k | speex_bits_pack(bits, 0, params->gain_bits); |
588 | 2.33k | SPEEX_MEMSET(exc, 0, nsf); |
589 | 2.33k | return start; |
590 | 2.33k | } |
591 | | |
592 | | #ifdef FIXED_POINT |
593 | | /* Check if we need to scale everything down in the pitch search to avoid overflows */ |
594 | 937k | for (i=0;i<nsf;i++) |
595 | 916k | { |
596 | 916k | if (ABS16(target[i])>16383) |
597 | 5.03k | { |
598 | 5.03k | scaledown=1; |
599 | 5.03k | break; |
600 | 5.03k | } |
601 | 916k | } |
602 | 2.80M | for (i=-end;i<0;i++) |
603 | 2.77M | { |
604 | 2.77M | if (ABS16(exc2[i])>16383) |
605 | 4.26k | { |
606 | 4.26k | scaledown=1; |
607 | 4.26k | break; |
608 | 4.26k | } |
609 | 2.77M | } |
610 | | #endif |
611 | 36.2k | if (N>end-start+1) |
612 | 3.98k | N=end-start+1; |
613 | 36.2k | if (end != start) |
614 | 30.7k | open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); |
615 | 5.47k | else |
616 | 5.47k | nbest[0] = start; |
617 | | |
618 | 36.2k | ALLOC(best_exc, nsf, spx_sig_t); |
619 | 36.2k | ALLOC(new_target, nsf, spx_word16_t); |
620 | 36.2k | ALLOC(best_target, nsf, spx_word16_t); |
621 | | |
622 | 207k | for (i=0;i<N;i++) |
623 | 171k | { |
624 | 171k | pitch=nbest[i]; |
625 | 171k | SPEEX_MEMSET(exc, 0, nsf); |
626 | 171k | err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, |
627 | 171k | bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); |
628 | 171k | if (err<best_err || best_err<0) |
629 | 48.3k | { |
630 | 48.3k | SPEEX_COPY(best_exc, exc, nsf); |
631 | 48.3k | SPEEX_COPY(best_target, new_target, nsf); |
632 | 48.3k | best_err=err; |
633 | 48.3k | best_pitch=pitch; |
634 | 48.3k | best_gain_index=cdbk_index; |
635 | 48.3k | } |
636 | 171k | } |
637 | | /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ |
638 | 9.52k | speex_bits_pack(bits, best_pitch-start, params->pitch_bits); |
639 | 9.52k | speex_bits_pack(bits, best_gain_index, params->gain_bits); |
640 | | #ifdef FIXED_POINT |
641 | 26.6k | *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4*best_gain_index+3],8), MAX32(1024,*cumul_gain)); |
642 | | #else |
643 | 9.52k | *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 | 36.2k | SPEEX_COPY(exc, best_exc, nsf); |
648 | 36.2k | SPEEX_COPY(target, best_target, nsf); |
649 | | #ifdef FIXED_POINT |
650 | | /* Scale target back up if needed */ |
651 | 26.6k | if (scaledown) |
652 | 6.55k | { |
653 | 268k | for (i=0;i<nsf;i++) |
654 | 262k | target[i]=SHL16(target[i],1); |
655 | 6.55k | } |
656 | | #endif |
657 | 9.52k | return pitch; |
658 | 38.5k | } Line | Count | Source | 555 | 10.2k | { | 556 | 10.2k | int i; | 557 | 10.2k | int cdbk_index, pitch=0, best_gain_index=0; | 558 | 10.2k | VARDECL(spx_sig_t *best_exc); | 559 | 10.2k | VARDECL(spx_word16_t *new_target); | 560 | 10.2k | VARDECL(spx_word16_t *best_target); | 561 | 10.2k | int best_pitch=0; | 562 | 10.2k | spx_word32_t err, best_err=-1; | 563 | 10.2k | int N; | 564 | 10.2k | const ltp_params *params; | 565 | 10.2k | const signed char *gain_cdbk; | 566 | 10.2k | int gain_cdbk_size; | 567 | 10.2k | int scaledown=0; | 568 | | | 569 | 10.2k | VARDECL(int *nbest); | 570 | | | 571 | 10.2k | params = (const ltp_params*) par; | 572 | 10.2k | gain_cdbk_size = 1<<params->gain_bits; | 573 | 10.2k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 574 | | | 575 | 10.2k | N=complexity; | 576 | 10.2k | if (N>10) | 577 | 0 | N=10; | 578 | 10.2k | if (N<1) | 579 | 1.62k | N=1; | 580 | | | 581 | 10.2k | ALLOC(nbest, N, int); | 582 | 10.2k | params = (const ltp_params*) par; | 583 | | | 584 | 10.2k | if (end<start) | 585 | 735 | { | 586 | 735 | speex_bits_pack(bits, 0, params->pitch_bits); | 587 | 735 | speex_bits_pack(bits, 0, params->gain_bits); | 588 | 735 | SPEEX_MEMSET(exc, 0, nsf); | 589 | 735 | return start; | 590 | 735 | } | 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.52k | if (N>end-start+1) | 612 | 889 | N=end-start+1; | 613 | 9.52k | if (end != start) | 614 | 8.35k | 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.52k | ALLOC(best_exc, nsf, spx_sig_t); | 619 | 9.52k | ALLOC(new_target, nsf, spx_word16_t); | 620 | 9.52k | ALLOC(best_target, nsf, spx_word16_t); | 621 | | | 622 | 58.6k | for (i=0;i<N;i++) | 623 | 49.1k | { | 624 | 49.1k | pitch=nbest[i]; | 625 | 49.1k | SPEEX_MEMSET(exc, 0, nsf); | 626 | 49.1k | err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, | 627 | 49.1k | bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); | 628 | 49.1k | if (err<best_err || best_err<0) | 629 | 11.8k | { | 630 | 11.8k | SPEEX_COPY(best_exc, exc, nsf); | 631 | 11.8k | SPEEX_COPY(best_target, new_target, nsf); | 632 | 11.8k | best_err=err; | 633 | 11.8k | best_pitch=pitch; | 634 | 11.8k | best_gain_index=cdbk_index; | 635 | 11.8k | } | 636 | 49.1k | } | 637 | | /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ | 638 | 9.52k | speex_bits_pack(bits, best_pitch-start, params->pitch_bits); | 639 | 9.52k | 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.52k | *cumul_gain = 0.03125*MAX32(1024,*cumul_gain)*params->gain_cdbk[4*best_gain_index+3]; | 644 | 9.52k | #endif | 645 | | /*printf ("%f\n", cumul_gain);*/ | 646 | | /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ | 647 | 9.52k | SPEEX_COPY(exc, best_exc, nsf); | 648 | 9.52k | 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.52k | return pitch; | 658 | 10.2k | } |
Line | Count | Source | 555 | 28.2k | { | 556 | 28.2k | int i; | 557 | 28.2k | int cdbk_index, pitch=0, best_gain_index=0; | 558 | 28.2k | VARDECL(spx_sig_t *best_exc); | 559 | 28.2k | VARDECL(spx_word16_t *new_target); | 560 | 28.2k | VARDECL(spx_word16_t *best_target); | 561 | 28.2k | int best_pitch=0; | 562 | 28.2k | spx_word32_t err, best_err=-1; | 563 | 28.2k | int N; | 564 | 28.2k | const ltp_params *params; | 565 | 28.2k | const signed char *gain_cdbk; | 566 | 28.2k | int gain_cdbk_size; | 567 | 28.2k | int scaledown=0; | 568 | | | 569 | 28.2k | VARDECL(int *nbest); | 570 | | | 571 | 28.2k | params = (const ltp_params*) par; | 572 | 28.2k | gain_cdbk_size = 1<<params->gain_bits; | 573 | 28.2k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 574 | | | 575 | 28.2k | N=complexity; | 576 | 28.2k | if (N>10) | 577 | 0 | N=10; | 578 | 28.2k | if (N<1) | 579 | 4.36k | N=1; | 580 | | | 581 | 28.2k | ALLOC(nbest, N, int); | 582 | 28.2k | params = (const ltp_params*) par; | 583 | | | 584 | 28.2k | if (end<start) | 585 | 1.60k | { | 586 | 1.60k | speex_bits_pack(bits, 0, params->pitch_bits); | 587 | 1.60k | speex_bits_pack(bits, 0, params->gain_bits); | 588 | 1.60k | SPEEX_MEMSET(exc, 0, nsf); | 589 | 1.60k | return start; | 590 | 1.60k | } | 591 | | | 592 | 26.6k | #ifdef FIXED_POINT | 593 | | /* Check if we need to scale everything down in the pitch search to avoid overflows */ | 594 | 937k | for (i=0;i<nsf;i++) | 595 | 916k | { | 596 | 916k | if (ABS16(target[i])>16383) | 597 | 5.03k | { | 598 | 5.03k | scaledown=1; | 599 | 5.03k | break; | 600 | 5.03k | } | 601 | 916k | } | 602 | 2.80M | for (i=-end;i<0;i++) | 603 | 2.77M | { | 604 | 2.77M | if (ABS16(exc2[i])>16383) | 605 | 4.26k | { | 606 | 4.26k | scaledown=1; | 607 | 4.26k | break; | 608 | 4.26k | } | 609 | 2.77M | } | 610 | 26.6k | #endif | 611 | 26.6k | if (N>end-start+1) | 612 | 3.09k | N=end-start+1; | 613 | 26.6k | if (end != start) | 614 | 22.3k | open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); | 615 | 4.30k | else | 616 | 4.30k | nbest[0] = start; | 617 | | | 618 | 26.6k | ALLOC(best_exc, nsf, spx_sig_t); | 619 | 26.6k | ALLOC(new_target, nsf, spx_word16_t); | 620 | 26.6k | ALLOC(best_target, nsf, spx_word16_t); | 621 | | | 622 | 148k | for (i=0;i<N;i++) | 623 | 122k | { | 624 | 122k | pitch=nbest[i]; | 625 | 122k | SPEEX_MEMSET(exc, 0, nsf); | 626 | 122k | err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, | 627 | 122k | bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); | 628 | 122k | if (err<best_err || best_err<0) | 629 | 36.5k | { | 630 | 36.5k | SPEEX_COPY(best_exc, exc, nsf); | 631 | 36.5k | SPEEX_COPY(best_target, new_target, nsf); | 632 | 36.5k | best_err=err; | 633 | 36.5k | best_pitch=pitch; | 634 | 36.5k | best_gain_index=cdbk_index; | 635 | 36.5k | } | 636 | 122k | } | 637 | | /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ | 638 | 26.6k | speex_bits_pack(bits, best_pitch-start, params->pitch_bits); | 639 | 26.6k | speex_bits_pack(bits, best_gain_index, params->gain_bits); | 640 | 26.6k | #ifdef FIXED_POINT | 641 | 26.6k | *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 | 26.6k | SPEEX_COPY(exc, best_exc, nsf); | 648 | 26.6k | SPEEX_COPY(target, best_target, nsf); | 649 | 26.6k | #ifdef FIXED_POINT | 650 | | /* Scale target back up if needed */ | 651 | 26.6k | if (scaledown) | 652 | 6.55k | { | 653 | 268k | for (i=0;i<nsf;i++) | 654 | 262k | target[i]=SHL16(target[i],1); | 655 | 6.55k | } | 656 | 26.6k | #endif | 657 | 26.6k | return pitch; | 658 | 28.2k | } |
|
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 | 125k | { |
680 | 125k | int i; |
681 | 125k | int pitch; |
682 | 125k | int gain_index; |
683 | 125k | spx_word16_t gain[3]; |
684 | 125k | const signed char *gain_cdbk; |
685 | 125k | int gain_cdbk_size; |
686 | 125k | const ltp_params *params; |
687 | | |
688 | 125k | params = (const ltp_params*) par; |
689 | 125k | gain_cdbk_size = 1<<params->gain_bits; |
690 | 125k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; |
691 | | |
692 | 125k | pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); |
693 | 125k | pitch += start; |
694 | 125k | 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 | 62.9k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); |
698 | 62.9k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); |
699 | 62.9k | 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 | 125k | 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 | 125k | *pitch_val = pitch; |
733 | 125k | gain_val[0]=gain[0]; |
734 | 125k | gain_val[1]=gain[1]; |
735 | 125k | gain_val[2]=gain[2]; |
736 | 125k | gain[0] = SHL16(gain[0],7); |
737 | 125k | gain[1] = SHL16(gain[1],7); |
738 | 125k | gain[2] = SHL16(gain[2],7); |
739 | 125k | SPEEX_MEMSET(exc_out, 0, nsf); |
740 | 503k | for (i=0;i<3;i++) |
741 | 377k | { |
742 | 377k | int j; |
743 | 377k | int tmp1, tmp3; |
744 | 377k | int pp=pitch+1-i; |
745 | 377k | tmp1=nsf; |
746 | 377k | if (tmp1>pp) |
747 | 313k | tmp1=pp; |
748 | 8.54M | for (j=0;j<tmp1;j++) |
749 | 8.17M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); |
750 | 377k | tmp3=nsf; |
751 | 377k | if (tmp3>pp+pitch) |
752 | 286k | tmp3=pp+pitch; |
753 | 5.59M | for (j=tmp1;j<tmp3;j++) |
754 | 5.22M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); |
755 | 377k | } |
756 | | /*for (i=0;i<nsf;i++) |
757 | | exc[i]=PSHR32(exc32[i],13);*/ |
758 | 125k | } Line | Count | Source | 679 | 62.9k | { | 680 | 62.9k | int i; | 681 | 62.9k | int pitch; | 682 | 62.9k | int gain_index; | 683 | 62.9k | spx_word16_t gain[3]; | 684 | 62.9k | const signed char *gain_cdbk; | 685 | 62.9k | int gain_cdbk_size; | 686 | 62.9k | const ltp_params *params; | 687 | | | 688 | 62.9k | params = (const ltp_params*) par; | 689 | 62.9k | gain_cdbk_size = 1<<params->gain_bits; | 690 | 62.9k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 691 | | | 692 | 62.9k | pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); | 693 | 62.9k | pitch += start; | 694 | 62.9k | 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 | 62.9k | gain[0] = 0.015625*gain_cdbk[gain_index*4]+.5; | 702 | 62.9k | gain[1] = 0.015625*gain_cdbk[gain_index*4+1]+.5; | 703 | 62.9k | gain[2] = 0.015625*gain_cdbk[gain_index*4+2]+.5; | 704 | 62.9k | #endif | 705 | | | 706 | 62.9k | 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 | 62.9k | *pitch_val = pitch; | 733 | 62.9k | gain_val[0]=gain[0]; | 734 | 62.9k | gain_val[1]=gain[1]; | 735 | 62.9k | gain_val[2]=gain[2]; | 736 | 62.9k | gain[0] = SHL16(gain[0],7); | 737 | 62.9k | gain[1] = SHL16(gain[1],7); | 738 | 62.9k | gain[2] = SHL16(gain[2],7); | 739 | 62.9k | SPEEX_MEMSET(exc_out, 0, nsf); | 740 | 251k | for (i=0;i<3;i++) | 741 | 188k | { | 742 | 188k | int j; | 743 | 188k | int tmp1, tmp3; | 744 | 188k | int pp=pitch+1-i; | 745 | 188k | tmp1=nsf; | 746 | 188k | if (tmp1>pp) | 747 | 156k | tmp1=pp; | 748 | 4.27M | for (j=0;j<tmp1;j++) | 749 | 4.08M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); | 750 | 188k | tmp3=nsf; | 751 | 188k | if (tmp3>pp+pitch) | 752 | 143k | tmp3=pp+pitch; | 753 | 2.79M | for (j=tmp1;j<tmp3;j++) | 754 | 2.61M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); | 755 | 188k | } | 756 | | /*for (i=0;i<nsf;i++) | 757 | | exc[i]=PSHR32(exc32[i],13);*/ | 758 | 62.9k | } |
Line | Count | Source | 679 | 62.9k | { | 680 | 62.9k | int i; | 681 | 62.9k | int pitch; | 682 | 62.9k | int gain_index; | 683 | 62.9k | spx_word16_t gain[3]; | 684 | 62.9k | const signed char *gain_cdbk; | 685 | 62.9k | int gain_cdbk_size; | 686 | 62.9k | const ltp_params *params; | 687 | | | 688 | 62.9k | params = (const ltp_params*) par; | 689 | 62.9k | gain_cdbk_size = 1<<params->gain_bits; | 690 | 62.9k | gain_cdbk = params->gain_cdbk + 4*gain_cdbk_size*cdbk_offset; | 691 | | | 692 | 62.9k | pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); | 693 | 62.9k | pitch += start; | 694 | 62.9k | gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); | 695 | | /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ | 696 | 62.9k | #ifdef FIXED_POINT | 697 | 62.9k | gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4]); | 698 | 62.9k | gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[gain_index*4+1]); | 699 | 62.9k | 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 | 62.9k | 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 | 62.9k | *pitch_val = pitch; | 733 | 62.9k | gain_val[0]=gain[0]; | 734 | 62.9k | gain_val[1]=gain[1]; | 735 | 62.9k | gain_val[2]=gain[2]; | 736 | 62.9k | gain[0] = SHL16(gain[0],7); | 737 | 62.9k | gain[1] = SHL16(gain[1],7); | 738 | 62.9k | gain[2] = SHL16(gain[2],7); | 739 | 62.9k | SPEEX_MEMSET(exc_out, 0, nsf); | 740 | 251k | for (i=0;i<3;i++) | 741 | 188k | { | 742 | 188k | int j; | 743 | 188k | int tmp1, tmp3; | 744 | 188k | int pp=pitch+1-i; | 745 | 188k | tmp1=nsf; | 746 | 188k | if (tmp1>pp) | 747 | 156k | tmp1=pp; | 748 | 4.27M | for (j=0;j<tmp1;j++) | 749 | 4.08M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp]); | 750 | 188k | tmp3=nsf; | 751 | 188k | if (tmp3>pp+pitch) | 752 | 143k | tmp3=pp+pitch; | 753 | 2.79M | for (j=tmp1;j<tmp3;j++) | 754 | 2.61M | exc_out[j]=MAC16_16(exc_out[j],gain[2-i],exc[j-pp-pitch]); | 755 | 188k | } | 756 | | /*for (i=0;i<nsf;i++) | 757 | | exc[i]=PSHR32(exc32[i],13);*/ | 758 | 62.9k | } |
|
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 | 63.0k | { |
786 | 63.0k | int i; |
787 | 63.0k | VARDECL(spx_word16_t *res); |
788 | 63.0k | ALLOC(res, nsf, spx_word16_t); |
789 | | #ifdef FIXED_POINT |
790 | 44.1k | if (pitch_coef>63) |
791 | 368 | pitch_coef=63; |
792 | | #else |
793 | 18.8k | if (pitch_coef>.99) |
794 | 140 | pitch_coef=.99; |
795 | | #endif |
796 | 1.99M | for (i=0;i<nsf&&i<start;i++) |
797 | 1.93M | { |
798 | 1.93M | exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); |
799 | 1.93M | } |
800 | 648k | for (;i<nsf;i++) |
801 | 585k | { |
802 | 585k | exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); |
803 | 585k | } |
804 | 2.58M | for (i=0;i<nsf;i++) |
805 | 2.52M | res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); |
806 | 63.0k | syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); |
807 | 2.58M | for (i=0;i<nsf;i++) |
808 | 2.52M | target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); |
809 | 63.0k | return start; |
810 | 63.0k | } Line | Count | Source | 785 | 18.8k | { | 786 | 18.8k | int i; | 787 | 18.8k | VARDECL(spx_word16_t *res); | 788 | 18.8k | ALLOC(res, nsf, spx_word16_t); | 789 | | #ifdef FIXED_POINT | 790 | | if (pitch_coef>63) | 791 | | pitch_coef=63; | 792 | | #else | 793 | 18.8k | if (pitch_coef>.99) | 794 | 140 | pitch_coef=.99; | 795 | 18.8k | #endif | 796 | 522k | for (i=0;i<nsf&&i<start;i++) | 797 | 503k | { | 798 | 503k | exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); | 799 | 503k | } | 800 | 270k | for (;i<nsf;i++) | 801 | 251k | { | 802 | 251k | exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); | 803 | 251k | } | 804 | 773k | for (i=0;i<nsf;i++) | 805 | 754k | res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); | 806 | 18.8k | syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); | 807 | 773k | for (i=0;i<nsf;i++) | 808 | 754k | target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); | 809 | 18.8k | return start; | 810 | 18.8k | } |
Line | Count | Source | 785 | 44.1k | { | 786 | 44.1k | int i; | 787 | 44.1k | VARDECL(spx_word16_t *res); | 788 | 44.1k | ALLOC(res, nsf, spx_word16_t); | 789 | 44.1k | #ifdef FIXED_POINT | 790 | 44.1k | if (pitch_coef>63) | 791 | 368 | pitch_coef=63; | 792 | | #else | 793 | | if (pitch_coef>.99) | 794 | | pitch_coef=.99; | 795 | | #endif | 796 | 1.47M | for (i=0;i<nsf&&i<start;i++) | 797 | 1.43M | { | 798 | 1.43M | exc[i]=MULT16_16(SHL16(pitch_coef, 7),exc2[i-start]); | 799 | 1.43M | } | 800 | 378k | for (;i<nsf;i++) | 801 | 334k | { | 802 | 334k | exc[i]=MULT16_32_Q15(SHL16(pitch_coef, 9),exc[i-start]); | 803 | 334k | } | 804 | 1.81M | for (i=0;i<nsf;i++) | 805 | 1.76M | res[i] = EXTRACT16(PSHR32(exc[i], SIG_SHIFT-1)); | 806 | 44.1k | syn_percep_zero16(res, ak, awk1, awk2, res, nsf, p, stack); | 807 | 1.81M | for (i=0;i<nsf;i++) | 808 | 1.76M | target[i]=EXTRACT16(SATURATE(SUB32(EXTEND32(target[i]),EXTEND32(res[i])),32700)); | 809 | 44.1k | return start; | 810 | 44.1k | } |
|
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 | 67.3k | { |
833 | 67.3k | int i; |
834 | | #ifdef FIXED_POINT |
835 | 33.6k | if (pitch_coef>63) |
836 | 4.51k | pitch_coef=63; |
837 | | #else |
838 | 33.6k | if (pitch_coef>.99) |
839 | 4.51k | pitch_coef=.99; |
840 | | #endif |
841 | 2.76M | for (i=0;i<nsf;i++) |
842 | 2.69M | { |
843 | 2.69M | exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); |
844 | 2.69M | exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); |
845 | 2.69M | } |
846 | 67.3k | *pitch_val = start; |
847 | 67.3k | gain_val[0]=gain_val[2]=0; |
848 | 67.3k | gain_val[1] = pitch_coef; |
849 | 67.3k | } Line | Count | Source | 832 | 33.6k | { | 833 | 33.6k | int i; | 834 | | #ifdef FIXED_POINT | 835 | | if (pitch_coef>63) | 836 | | pitch_coef=63; | 837 | | #else | 838 | 33.6k | if (pitch_coef>.99) | 839 | 4.51k | pitch_coef=.99; | 840 | 33.6k | #endif | 841 | 1.38M | for (i=0;i<nsf;i++) | 842 | 1.34M | { | 843 | 1.34M | exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); | 844 | 1.34M | exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); | 845 | 1.34M | } | 846 | 33.6k | *pitch_val = start; | 847 | 33.6k | gain_val[0]=gain_val[2]=0; | 848 | 33.6k | gain_val[1] = pitch_coef; | 849 | 33.6k | } |
Line | Count | Source | 832 | 33.6k | { | 833 | 33.6k | int i; | 834 | 33.6k | #ifdef FIXED_POINT | 835 | 33.6k | if (pitch_coef>63) | 836 | 4.51k | pitch_coef=63; | 837 | | #else | 838 | | if (pitch_coef>.99) | 839 | | pitch_coef=.99; | 840 | | #endif | 841 | 1.38M | for (i=0;i<nsf;i++) | 842 | 1.34M | { | 843 | 1.34M | exc_out[i]=MULT16_16(exc[i-start],SHL16(pitch_coef,7)); | 844 | 1.34M | exc[i] = EXTRACT16(PSHR32(exc_out[i],13)); | 845 | 1.34M | } | 846 | 33.6k | *pitch_val = start; | 847 | 33.6k | gain_val[0]=gain_val[2]=0; | 848 | 33.6k | gain_val[1] = pitch_coef; | 849 | 33.6k | } |
|
850 | | #endif /* DISABLE_DECODER */ |