diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libspeex/cb_search.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/cb_search.c')
-rw-r--r-- | lib/rbcodec/codecs/libspeex/cb_search.c | 621 |
1 files changed, 621 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libspeex/cb_search.c b/lib/rbcodec/codecs/libspeex/cb_search.c new file mode 100644 index 0000000000..35fe3a2f67 --- /dev/null +++ b/lib/rbcodec/codecs/libspeex/cb_search.c | |||
@@ -0,0 +1,621 @@ | |||
1 | /* Copyright (C) 2002-2006 Jean-Marc Valin | ||
2 | File: cb_search.c | ||
3 | |||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | - Neither the name of the Xiph.org Foundation nor the names of its | ||
16 | contributors may be used to endorse or promote products derived from | ||
17 | this software without specific prior written permission. | ||
18 | |||
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
20 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
23 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
24 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
25 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
26 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
27 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
28 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
30 | */ | ||
31 | |||
32 | #ifdef HAVE_CONFIG_H | ||
33 | #include "config-speex.h" | ||
34 | #endif | ||
35 | |||
36 | #include "cb_search.h" | ||
37 | #include "filters.h" | ||
38 | #include "stack_alloc.h" | ||
39 | #include "vq.h" | ||
40 | #include "arch.h" | ||
41 | #include "math_approx.h" | ||
42 | #include "os_support.h" | ||
43 | |||
44 | #ifdef _USE_SSE | ||
45 | #include "cb_search_sse.h" | ||
46 | #elif defined(ARM4_ASM) || defined(ARM5E_ASM) | ||
47 | #include "cb_search_arm4.h" | ||
48 | #elif defined(BFIN_ASM) | ||
49 | #include "cb_search_bfin.h" | ||
50 | #endif | ||
51 | |||
52 | #ifndef SPEEX_DISABLE_ENCODER | ||
53 | #ifndef OVERRIDE_COMPUTE_WEIGHTED_CODEBOOK | ||
54 | static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack) | ||
55 | { | ||
56 | int i, j, k; | ||
57 | VARDECL(spx_word16_t *shape); | ||
58 | ALLOC(shape, subvect_size, spx_word16_t); | ||
59 | for (i=0;i<shape_cb_size;i++) | ||
60 | { | ||
61 | spx_word16_t *res; | ||
62 | |||
63 | res = resp+i*subvect_size; | ||
64 | for (k=0;k<subvect_size;k++) | ||
65 | shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k]; | ||
66 | E[i]=0; | ||
67 | |||
68 | /* Compute codeword response using convolution with impulse response */ | ||
69 | for(j=0;j<subvect_size;j++) | ||
70 | { | ||
71 | spx_word32_t resj=0; | ||
72 | spx_word16_t res16; | ||
73 | for (k=0;k<=j;k++) | ||
74 | resj = MAC16_16(resj,shape[k],r[j-k]); | ||
75 | #ifdef FIXED_POINT | ||
76 | res16 = EXTRACT16(SHR32(resj, 13)); | ||
77 | #else | ||
78 | res16 = 0.03125f*resj; | ||
79 | #endif | ||
80 | /* Compute codeword energy */ | ||
81 | E[i]=MAC16_16(E[i],res16,res16); | ||
82 | res[j] = res16; | ||
83 | /*printf ("%d\n", (int)res[j]);*/ | ||
84 | } | ||
85 | } | ||
86 | |||
87 | } | ||
88 | #endif | ||
89 | |||
90 | #ifndef OVERRIDE_TARGET_UPDATE | ||
91 | static inline void target_update(spx_word16_t *t, spx_word16_t g, spx_word16_t *r, int len) | ||
92 | { | ||
93 | int n; | ||
94 | for (n=0;n<len;n++) | ||
95 | t[n] = SUB16(t[n],PSHR32(MULT16_16(g,r[n]),13)); | ||
96 | } | ||
97 | #endif | ||
98 | |||
99 | |||
100 | |||
101 | static void split_cb_search_shape_sign_N1( | ||
102 | spx_word16_t target[], /* target vector */ | ||
103 | spx_coef_t ak[], /* LPCs for this subframe */ | ||
104 | spx_coef_t awk1[], /* Weighted LPCs for this subframe */ | ||
105 | spx_coef_t awk2[], /* Weighted LPCs for this subframe */ | ||
106 | const void *par, /* Codebook/search parameters*/ | ||
107 | int p, /* number of LPC coeffs */ | ||
108 | int nsf, /* number of samples in subframe */ | ||
109 | spx_sig_t *exc, | ||
110 | spx_word16_t *r, | ||
111 | SpeexBits *bits, | ||
112 | char *stack, | ||
113 | int update_target | ||
114 | ) | ||
115 | { | ||
116 | int i,j,m,q; | ||
117 | VARDECL(spx_word16_t *resp); | ||
118 | #ifdef _USE_SSE | ||
119 | VARDECL(__m128 *resp2); | ||
120 | VARDECL(__m128 *E); | ||
121 | #else | ||
122 | spx_word16_t *resp2; | ||
123 | VARDECL(spx_word32_t *E); | ||
124 | #endif | ||
125 | VARDECL(spx_word16_t *t); | ||
126 | VARDECL(spx_sig_t *e); | ||
127 | const signed char *shape_cb; | ||
128 | int shape_cb_size, subvect_size, nb_subvect; | ||
129 | const split_cb_params *params; | ||
130 | int best_index; | ||
131 | spx_word32_t best_dist; | ||
132 | int have_sign; | ||
133 | |||
134 | params = (const split_cb_params *) par; | ||
135 | subvect_size = params->subvect_size; | ||
136 | nb_subvect = params->nb_subvect; | ||
137 | shape_cb_size = 1<<params->shape_bits; | ||
138 | shape_cb = params->shape_cb; | ||
139 | have_sign = params->have_sign; | ||
140 | ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t); | ||
141 | #ifdef _USE_SSE | ||
142 | ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128); | ||
143 | ALLOC(E, shape_cb_size>>2, __m128); | ||
144 | #else | ||
145 | resp2 = resp; | ||
146 | ALLOC(E, shape_cb_size, spx_word32_t); | ||
147 | #endif | ||
148 | ALLOC(t, nsf, spx_word16_t); | ||
149 | ALLOC(e, nsf, spx_sig_t); | ||
150 | |||
151 | /* FIXME: Do we still need to copy the target? */ | ||
152 | SPEEX_COPY(t, target, nsf); | ||
153 | |||
154 | compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack); | ||
155 | |||
156 | for (i=0;i<nb_subvect;i++) | ||
157 | { | ||
158 | spx_word16_t *x=t+subvect_size*i; | ||
159 | /*Find new n-best based on previous n-best j*/ | ||
160 | if (have_sign) | ||
161 | vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack); | ||
162 | else | ||
163 | vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack); | ||
164 | |||
165 | speex_bits_pack(bits,best_index,params->shape_bits+have_sign); | ||
166 | |||
167 | { | ||
168 | int rind; | ||
169 | spx_word16_t *res; | ||
170 | spx_word16_t sign=1; | ||
171 | rind = best_index; | ||
172 | if (rind>=shape_cb_size) | ||
173 | { | ||
174 | sign=-1; | ||
175 | rind-=shape_cb_size; | ||
176 | } | ||
177 | res = resp+rind*subvect_size; | ||
178 | if (sign>0) | ||
179 | for (m=0;m<subvect_size;m++) | ||
180 | t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]); | ||
181 | else | ||
182 | for (m=0;m<subvect_size;m++) | ||
183 | t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]); | ||
184 | |||
185 | #ifdef FIXED_POINT | ||
186 | if (sign==1) | ||
187 | { | ||
188 | for (j=0;j<subvect_size;j++) | ||
189 | e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5); | ||
190 | } else { | ||
191 | for (j=0;j<subvect_size;j++) | ||
192 | e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5)); | ||
193 | } | ||
194 | #else | ||
195 | for (j=0;j<subvect_size;j++) | ||
196 | e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j]; | ||
197 | #endif | ||
198 | |||
199 | } | ||
200 | |||
201 | for (m=0;m<subvect_size;m++) | ||
202 | { | ||
203 | spx_word16_t g; | ||
204 | int rind; | ||
205 | spx_word16_t sign=1; | ||
206 | rind = best_index; | ||
207 | if (rind>=shape_cb_size) | ||
208 | { | ||
209 | sign=-1; | ||
210 | rind-=shape_cb_size; | ||
211 | } | ||
212 | |||
213 | q=subvect_size-m; | ||
214 | #ifdef FIXED_POINT | ||
215 | g=sign*shape_cb[rind*subvect_size+m]; | ||
216 | #else | ||
217 | g=sign*0.03125*shape_cb[rind*subvect_size+m]; | ||
218 | #endif | ||
219 | target_update(t+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1)); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /* Update excitation */ | ||
224 | /* FIXME: We could update the excitation directly above */ | ||
225 | for (j=0;j<nsf;j++) | ||
226 | exc[j]=ADD32(exc[j],e[j]); | ||
227 | |||
228 | /* Update target: only update target if necessary */ | ||
229 | if (update_target) | ||
230 | { | ||
231 | VARDECL(spx_word16_t *r2); | ||
232 | ALLOC(r2, nsf, spx_word16_t); | ||
233 | for (j=0;j<nsf;j++) | ||
234 | r2[j] = EXTRACT16(PSHR32(e[j] ,6)); | ||
235 | syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack); | ||
236 | for (j=0;j<nsf;j++) | ||
237 | target[j]=SUB16(target[j],PSHR16(r2[j],2)); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | |||
242 | |||
243 | void split_cb_search_shape_sign( | ||
244 | spx_word16_t target[], /* target vector */ | ||
245 | spx_coef_t ak[], /* LPCs for this subframe */ | ||
246 | spx_coef_t awk1[], /* Weighted LPCs for this subframe */ | ||
247 | spx_coef_t awk2[], /* Weighted LPCs for this subframe */ | ||
248 | const void *par, /* Codebook/search parameters*/ | ||
249 | int p, /* number of LPC coeffs */ | ||
250 | int nsf, /* number of samples in subframe */ | ||
251 | spx_sig_t *exc, | ||
252 | spx_word16_t *r, | ||
253 | SpeexBits *bits, | ||
254 | char *stack, | ||
255 | int complexity, | ||
256 | int update_target | ||
257 | ) | ||
258 | { | ||
259 | int i,j,k,m,n,q; | ||
260 | VARDECL(spx_word16_t *resp); | ||
261 | #ifdef _USE_SSE | ||
262 | VARDECL(__m128 *resp2); | ||
263 | VARDECL(__m128 *E); | ||
264 | #else | ||
265 | spx_word16_t *resp2; | ||
266 | VARDECL(spx_word32_t *E); | ||
267 | #endif | ||
268 | VARDECL(spx_word16_t *t); | ||
269 | VARDECL(spx_sig_t *e); | ||
270 | VARDECL(spx_word16_t *tmp); | ||
271 | VARDECL(spx_word32_t *ndist); | ||
272 | VARDECL(spx_word32_t *odist); | ||
273 | VARDECL(int *itmp); | ||
274 | VARDECL(spx_word16_t **ot2); | ||
275 | VARDECL(spx_word16_t **nt2); | ||
276 | spx_word16_t **ot, **nt; | ||
277 | VARDECL(int **nind); | ||
278 | VARDECL(int **oind); | ||
279 | VARDECL(int *ind); | ||
280 | const signed char *shape_cb; | ||
281 | int shape_cb_size, subvect_size, nb_subvect; | ||
282 | const split_cb_params *params; | ||
283 | int N=2; | ||
284 | VARDECL(int *best_index); | ||
285 | VARDECL(spx_word32_t *best_dist); | ||
286 | VARDECL(int *best_nind); | ||
287 | VARDECL(int *best_ntarget); | ||
288 | int have_sign; | ||
289 | N=complexity; | ||
290 | if (N>10) | ||
291 | N=10; | ||
292 | /* Complexity isn't as important for the codebooks as it is for the pitch */ | ||
293 | N=(2*N)/3; | ||
294 | if (N<1) | ||
295 | N=1; | ||
296 | if (N==1) | ||
297 | { | ||
298 | split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,update_target); | ||
299 | return; | ||
300 | } | ||
301 | ALLOC(ot2, N, spx_word16_t*); | ||
302 | ALLOC(nt2, N, spx_word16_t*); | ||
303 | ALLOC(oind, N, int*); | ||
304 | ALLOC(nind, N, int*); | ||
305 | |||
306 | params = (const split_cb_params *) par; | ||
307 | subvect_size = params->subvect_size; | ||
308 | nb_subvect = params->nb_subvect; | ||
309 | shape_cb_size = 1<<params->shape_bits; | ||
310 | shape_cb = params->shape_cb; | ||
311 | have_sign = params->have_sign; | ||
312 | ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t); | ||
313 | #ifdef _USE_SSE | ||
314 | ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128); | ||
315 | ALLOC(E, shape_cb_size>>2, __m128); | ||
316 | #else | ||
317 | resp2 = resp; | ||
318 | ALLOC(E, shape_cb_size, spx_word32_t); | ||
319 | #endif | ||
320 | ALLOC(t, nsf, spx_word16_t); | ||
321 | ALLOC(e, nsf, spx_sig_t); | ||
322 | ALLOC(ind, nb_subvect, int); | ||
323 | |||
324 | ALLOC(tmp, 2*N*nsf, spx_word16_t); | ||
325 | for (i=0;i<N;i++) | ||
326 | { | ||
327 | ot2[i]=tmp+2*i*nsf; | ||
328 | nt2[i]=tmp+(2*i+1)*nsf; | ||
329 | } | ||
330 | ot=ot2; | ||
331 | nt=nt2; | ||
332 | ALLOC(best_index, N, int); | ||
333 | ALLOC(best_dist, N, spx_word32_t); | ||
334 | ALLOC(best_nind, N, int); | ||
335 | ALLOC(best_ntarget, N, int); | ||
336 | ALLOC(ndist, N, spx_word32_t); | ||
337 | ALLOC(odist, N, spx_word32_t); | ||
338 | |||
339 | ALLOC(itmp, 2*N*nb_subvect, int); | ||
340 | for (i=0;i<N;i++) | ||
341 | { | ||
342 | nind[i]=itmp+2*i*nb_subvect; | ||
343 | oind[i]=itmp+(2*i+1)*nb_subvect; | ||
344 | } | ||
345 | |||
346 | SPEEX_COPY(t, target, nsf); | ||
347 | |||
348 | for (j=0;j<N;j++) | ||
349 | SPEEX_COPY(&ot[j][0], t, nsf); | ||
350 | |||
351 | /* Pre-compute codewords response and energy */ | ||
352 | compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack); | ||
353 | |||
354 | for (j=0;j<N;j++) | ||
355 | odist[j]=0; | ||
356 | |||
357 | /*For all subvectors*/ | ||
358 | for (i=0;i<nb_subvect;i++) | ||
359 | { | ||
360 | /*"erase" nbest list*/ | ||
361 | for (j=0;j<N;j++) | ||
362 | ndist[j]=VERY_LARGE32; | ||
363 | /* This is not strictly necessary, but it provides an additonal safety | ||
364 | to prevent crashes in case something goes wrong in the previous | ||
365 | steps (e.g. NaNs) */ | ||
366 | for (j=0;j<N;j++) | ||
367 | best_nind[j] = best_ntarget[j] = 0; | ||
368 | /*For all n-bests of previous subvector*/ | ||
369 | for (j=0;j<N;j++) | ||
370 | { | ||
371 | spx_word16_t *x=ot[j]+subvect_size*i; | ||
372 | spx_word32_t tener = 0; | ||
373 | for (m=0;m<subvect_size;m++) | ||
374 | tener = MAC16_16(tener, x[m],x[m]); | ||
375 | #ifdef FIXED_POINT | ||
376 | tener = SHR32(tener,1); | ||
377 | #else | ||
378 | tener *= .5; | ||
379 | #endif | ||
380 | /*Find new n-best based on previous n-best j*/ | ||
381 | if (have_sign) | ||
382 | vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack); | ||
383 | else | ||
384 | vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack); | ||
385 | |||
386 | /*For all new n-bests*/ | ||
387 | for (k=0;k<N;k++) | ||
388 | { | ||
389 | /* Compute total distance (including previous sub-vectors */ | ||
390 | spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener); | ||
391 | |||
392 | /*update n-best list*/ | ||
393 | if (err<ndist[N-1]) | ||
394 | { | ||
395 | for (m=0;m<N;m++) | ||
396 | { | ||
397 | if (err < ndist[m]) | ||
398 | { | ||
399 | for (n=N-1;n>m;n--) | ||
400 | { | ||
401 | ndist[n] = ndist[n-1]; | ||
402 | best_nind[n] = best_nind[n-1]; | ||
403 | best_ntarget[n] = best_ntarget[n-1]; | ||
404 | } | ||
405 | /* n is equal to m here, so they're interchangeable */ | ||
406 | ndist[m] = err; | ||
407 | best_nind[n] = best_index[k]; | ||
408 | best_ntarget[n] = j; | ||
409 | break; | ||
410 | } | ||
411 | } | ||
412 | } | ||
413 | } | ||
414 | if (i==0) | ||
415 | break; | ||
416 | } | ||
417 | for (j=0;j<N;j++) | ||
418 | { | ||
419 | /*previous target (we don't care what happened before*/ | ||
420 | for (m=(i+1)*subvect_size;m<nsf;m++) | ||
421 | nt[j][m]=ot[best_ntarget[j]][m]; | ||
422 | |||
423 | /* New code: update the rest of the target only if it's worth it */ | ||
424 | for (m=0;m<subvect_size;m++) | ||
425 | { | ||
426 | spx_word16_t g; | ||
427 | int rind; | ||
428 | spx_word16_t sign=1; | ||
429 | rind = best_nind[j]; | ||
430 | if (rind>=shape_cb_size) | ||
431 | { | ||
432 | sign=-1; | ||
433 | rind-=shape_cb_size; | ||
434 | } | ||
435 | |||
436 | q=subvect_size-m; | ||
437 | #ifdef FIXED_POINT | ||
438 | g=sign*shape_cb[rind*subvect_size+m]; | ||
439 | #else | ||
440 | g=sign*0.03125*shape_cb[rind*subvect_size+m]; | ||
441 | #endif | ||
442 | target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1)); | ||
443 | } | ||
444 | |||
445 | for (q=0;q<nb_subvect;q++) | ||
446 | nind[j][q]=oind[best_ntarget[j]][q]; | ||
447 | nind[j][i]=best_nind[j]; | ||
448 | } | ||
449 | |||
450 | /*update old-new data*/ | ||
451 | /* just swap pointers instead of a long copy */ | ||
452 | { | ||
453 | spx_word16_t **tmp2; | ||
454 | tmp2=ot; | ||
455 | ot=nt; | ||
456 | nt=tmp2; | ||
457 | } | ||
458 | for (j=0;j<N;j++) | ||
459 | for (m=0;m<nb_subvect;m++) | ||
460 | oind[j][m]=nind[j][m]; | ||
461 | for (j=0;j<N;j++) | ||
462 | odist[j]=ndist[j]; | ||
463 | } | ||
464 | |||
465 | /*save indices*/ | ||
466 | for (i=0;i<nb_subvect;i++) | ||
467 | { | ||
468 | ind[i]=nind[0][i]; | ||
469 | speex_bits_pack(bits,ind[i],params->shape_bits+have_sign); | ||
470 | } | ||
471 | |||
472 | /* Put everything back together */ | ||
473 | for (i=0;i<nb_subvect;i++) | ||
474 | { | ||
475 | int rind; | ||
476 | spx_word16_t sign=1; | ||
477 | rind = ind[i]; | ||
478 | if (rind>=shape_cb_size) | ||
479 | { | ||
480 | sign=-1; | ||
481 | rind-=shape_cb_size; | ||
482 | } | ||
483 | #ifdef FIXED_POINT | ||
484 | if (sign==1) | ||
485 | { | ||
486 | for (j=0;j<subvect_size;j++) | ||
487 | e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5); | ||
488 | } else { | ||
489 | for (j=0;j<subvect_size;j++) | ||
490 | e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5)); | ||
491 | } | ||
492 | #else | ||
493 | for (j=0;j<subvect_size;j++) | ||
494 | e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j]; | ||
495 | #endif | ||
496 | } | ||
497 | /* Update excitation */ | ||
498 | for (j=0;j<nsf;j++) | ||
499 | exc[j]=ADD32(exc[j],e[j]); | ||
500 | |||
501 | /* Update target: only update target if necessary */ | ||
502 | if (update_target) | ||
503 | { | ||
504 | VARDECL(spx_word16_t *r2); | ||
505 | ALLOC(r2, nsf, spx_word16_t); | ||
506 | for (j=0;j<nsf;j++) | ||
507 | r2[j] = EXTRACT16(PSHR32(e[j] ,6)); | ||
508 | syn_percep_zero16(r2, ak, awk1, awk2, r2, nsf,p, stack); | ||
509 | for (j=0;j<nsf;j++) | ||
510 | target[j]=SUB16(target[j],PSHR16(r2[j],2)); | ||
511 | } | ||
512 | } | ||
513 | #endif /* SPEEX_DISABLE_ENCODER*/ | ||
514 | |||
515 | |||
516 | void split_cb_shape_sign_unquant( | ||
517 | spx_sig_t *exc, | ||
518 | const void *par, /* non-overlapping codebook */ | ||
519 | int nsf, /* number of samples in subframe */ | ||
520 | SpeexBits *bits, | ||
521 | char *stack, | ||
522 | spx_int32_t *seed | ||
523 | ) | ||
524 | { | ||
525 | (void)nsf; | ||
526 | (void)stack; | ||
527 | (void)seed; | ||
528 | int i,j; | ||
529 | VARDECL(int *ind); | ||
530 | VARDECL(int *signs); | ||
531 | const signed char *shape_cb; | ||
532 | int subvect_size, nb_subvect; | ||
533 | const split_cb_params *params; | ||
534 | int have_sign; | ||
535 | |||
536 | params = (const split_cb_params *) par; | ||
537 | subvect_size = params->subvect_size; | ||
538 | nb_subvect = params->nb_subvect; | ||
539 | shape_cb = params->shape_cb; | ||
540 | have_sign = params->have_sign; | ||
541 | |||
542 | ALLOC(ind, nb_subvect, int); | ||
543 | ALLOC(signs, nb_subvect, int); | ||
544 | |||
545 | /* Decode codewords and gains */ | ||
546 | for (i=0;i<nb_subvect;i++) | ||
547 | { | ||
548 | if (have_sign) | ||
549 | signs[i] = speex_bits_unpack_unsigned(bits, 1); | ||
550 | else | ||
551 | signs[i] = 0; | ||
552 | ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits); | ||
553 | } | ||
554 | /* Compute decoded excitation */ | ||
555 | for (i=0;i<nb_subvect;i++) | ||
556 | { | ||
557 | spx_word16_t s=1; | ||
558 | if (signs[i]) | ||
559 | s=-1; | ||
560 | #ifdef FIXED_POINT | ||
561 | if (s==1) | ||
562 | { | ||
563 | for (j=0;j<subvect_size;j++) | ||
564 | exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5); | ||
565 | } else { | ||
566 | for (j=0;j<subvect_size;j++) | ||
567 | exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5)); | ||
568 | } | ||
569 | #else | ||
570 | for (j=0;j<subvect_size;j++) | ||
571 | exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j]; | ||
572 | #endif | ||
573 | } | ||
574 | } | ||
575 | |||
576 | #ifndef SPEEX_DISABLE_ENCODER | ||
577 | void noise_codebook_quant( | ||
578 | spx_word16_t target[], /* target vector */ | ||
579 | spx_coef_t ak[], /* LPCs for this subframe */ | ||
580 | spx_coef_t awk1[], /* Weighted LPCs for this subframe */ | ||
581 | spx_coef_t awk2[], /* Weighted LPCs for this subframe */ | ||
582 | const void *par, /* Codebook/search parameters*/ | ||
583 | int p, /* number of LPC coeffs */ | ||
584 | int nsf, /* number of samples in subframe */ | ||
585 | spx_sig_t *exc, | ||
586 | spx_word16_t *r, | ||
587 | SpeexBits *bits, | ||
588 | char *stack, | ||
589 | int complexity, | ||
590 | int update_target | ||
591 | ) | ||
592 | { | ||
593 | int i; | ||
594 | VARDECL(spx_word16_t *tmp); | ||
595 | ALLOC(tmp, nsf, spx_word16_t); | ||
596 | residue_percep_zero16(target, ak, awk1, awk2, tmp, nsf, p, stack); | ||
597 | |||
598 | for (i=0;i<nsf;i++) | ||
599 | exc[i]+=SHL32(EXTEND32(tmp[i]),8); | ||
600 | SPEEX_MEMSET(target, 0, nsf); | ||
601 | } | ||
602 | #endif /* SPEEX_DISABLE_ENCODER */ | ||
603 | |||
604 | |||
605 | void noise_codebook_unquant( | ||
606 | spx_sig_t *exc, | ||
607 | const void *par, /* non-overlapping codebook */ | ||
608 | int nsf, /* number of samples in subframe */ | ||
609 | SpeexBits *bits, | ||
610 | char *stack, | ||
611 | spx_int32_t *seed | ||
612 | ) | ||
613 | { | ||
614 | (void)par; | ||
615 | (void)bits; | ||
616 | (void)stack; | ||
617 | int i; | ||
618 | /* FIXME: This is bad, but I don't think the function ever gets called anyway */ | ||
619 | for (i=0;i<nsf;i++) | ||
620 | exc[i]=SHL32(EXTEND32(speex_rand(1, seed)),SIG_SHIFT); | ||
621 | } | ||