1
/* Copyright (C) 2002 Jean-Marc Valin
4
Redistribution and use in source and binary forms, with or without
5
modification, are permitted provided that the following conditions
8
- Redistributions of source code must retain the above copyright
9
notice, this list of conditions and the following disclaimer.
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.
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.
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.
33
#include "cb_search.h"
35
#include "stack_alloc.h"
41
#include "cb_search_sse.h"
44
static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *r, spx_word16_t *resp, float *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
47
for (i=0;i<shape_cb_size;i++)
50
const signed char *shape;
52
res = resp+i*subvect_size;
53
shape = shape_cb+i*subvect_size;
55
/* Compute codeword response using convolution with impulse response */
56
for(j=0;j<subvect_size;j++)
60
resj = MAC16_16_Q11(resj,shape[k],r[j-k]);
65
/*printf ("%d\n", (int)res[j]);*/
68
/* Compute codeword energy */
70
for(j=0;j<subvect_size;j++)
71
E[i]=ADD32(E[i],MULT16_16(res[j],res[j]));
79
void split_cb_search_shape_sign(
80
spx_sig_t target[], /* target vector */
81
spx_coef_t ak[], /* LPCs for this subframe */
82
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
83
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
84
const void *par, /* Codebook/search parameters*/
85
int p, /* number of LPC coeffs */
86
int nsf, /* number of samples in subframe */
106
spx_word32_t *ndist, *odist;
108
spx_word16_t **ot, **nt;
111
const signed char *shape_cb;
112
int shape_cb_size, subvect_size, nb_subvect;
113
split_cb_params *params;
116
spx_word32_t *best_dist;
122
ot=PUSH(stack, N, spx_word16_t*);
123
nt=PUSH(stack, N, spx_word16_t*);
124
oind=PUSH(stack, N, int*);
125
nind=PUSH(stack, N, int*);
127
params = (split_cb_params *) par;
128
subvect_size = params->subvect_size;
129
nb_subvect = params->nb_subvect;
130
shape_cb_size = 1<<params->shape_bits;
131
shape_cb = params->shape_cb;
132
have_sign = params->have_sign;
133
resp = PUSH(stack, shape_cb_size*subvect_size, spx_word16_t);
135
resp2 = PUSH(stack, (shape_cb_size*subvect_size)>>2, __m128);
136
E = PUSH(stack, shape_cb_size>>2, __m128);
139
E = PUSH(stack, shape_cb_size, spx_word32_t);
141
t = PUSH(stack, nsf, spx_word16_t);
142
e = PUSH(stack, nsf, spx_sig_t);
143
r2 = PUSH(stack, nsf, spx_sig_t);
144
ind = PUSH(stack, nb_subvect, int);
146
tmp = PUSH(stack, 2*N*nsf, spx_word16_t);
154
best_index = PUSH(stack, N, int);
155
best_dist = PUSH(stack, N, spx_word32_t);
156
ndist = PUSH(stack, N, spx_word32_t);
157
odist = PUSH(stack, N, spx_word32_t);
159
itmp = PUSH(stack, 2*N*nb_subvect, int);
166
for (j=0;j<nb_subvect;j++)
167
nind[i][j]=oind[i][j]=-1;
170
/* FIXME: make that adaptive? */
172
t[i]=SHR(target[i],6);
178
/*for (i=0;i<nsf;i++)
179
printf ("%d\n", (int)t[i]);*/
181
/* Pre-compute codewords response and energy */
182
compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
186
/*For all subvectors*/
187
for (i=0;i<nb_subvect;i++)
189
/*"erase" nbest list*/
193
/*For all n-bests of previous subvector*/
196
spx_word16_t *x=ot[j]+subvect_size*i;
197
/*Find new n-best based on previous n-best j*/
199
vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
201
vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
203
/*For all new n-bests*/
212
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
215
/* New code: update only enough of the target to calculate error*/
220
rind = best_index[k];
221
if (rind>=shape_cb_size)
226
res = resp+rind*subvect_size;
228
for (m=0;m<subvect_size;m++)
229
t[subvect_size*i+m] -= res[m];
231
for (m=0;m<subvect_size;m++)
232
t[subvect_size*i+m] += res[m];
235
/*compute error (distance)*/
237
for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
239
/*update n-best list*/
240
if (err<ndist[N-1] || ndist[N-1]<-1)
243
/*previous target (we don't care what happened before*/
244
for (m=(i+1)*subvect_size;m<nsf;m++)
246
/* New code: update the rest of the target only if it's worth it */
247
for (m=0;m<subvect_size;m++)
252
rind = best_index[k];
253
if (rind>=shape_cb_size)
261
g=sign*shape_cb[rind*subvect_size+m];
262
for (n=subvect_size*(i+1);n<nsf;n++,q++)
263
t[n] = SUB32(t[n],MULT16_16_Q11(g,r[q]));
265
g=sign*0.03125*shape_cb[rind*subvect_size+m];
266
for (n=subvect_size*(i+1);n<nsf;n++,q++)
267
t[n] = SUB32(t[n],g*r[q]);
274
if (err < ndist[m] || ndist[m]<-1)
278
for (q=(i+1)*subvect_size;q<nsf;q++)
280
for (q=0;q<nb_subvect;q++)
281
nind[n][q]=nind[n-1][q];
284
for (q=(i+1)*subvect_size;q<nsf;q++)
286
for (q=0;q<nb_subvect;q++)
287
nind[m][q]=oind[j][q];
288
nind[m][i]=best_index[k];
299
/*update old-new data*/
300
/* just swap pointers instead of a long copy */
308
for (m=0;m<nb_subvect;m++)
309
oind[j][m]=nind[j][m];
315
for (i=0;i<nb_subvect;i++)
318
speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
321
/* Put everything back together */
322
for (i=0;i<nb_subvect;i++)
327
if (rind>=shape_cb_size)
335
for (j=0;j<subvect_size;j++)
336
e[subvect_size*i+j]=SHL((spx_word32_t)shape_cb[rind*subvect_size+j],SIG_SHIFT-5);
338
for (j=0;j<subvect_size;j++)
339
e[subvect_size*i+j]=-SHL((spx_word32_t)shape_cb[rind*subvect_size+j],SIG_SHIFT-5);
342
for (j=0;j<subvect_size;j++)
343
e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
346
/* Update excitation */
351
syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
358
void split_cb_shape_sign_unquant(
360
const void *par, /* non-overlapping codebook */
361
int nsf, /* number of samples in subframe */
368
const signed char *shape_cb;
369
int shape_cb_size, subvect_size, nb_subvect;
370
split_cb_params *params;
373
params = (split_cb_params *) par;
374
subvect_size = params->subvect_size;
375
nb_subvect = params->nb_subvect;
376
shape_cb_size = 1<<params->shape_bits;
377
shape_cb = params->shape_cb;
378
have_sign = params->have_sign;
380
ind = PUSH(stack, nb_subvect, int);
381
signs = PUSH(stack, nb_subvect, int);
383
/* Decode codewords and gains */
384
for (i=0;i<nb_subvect;i++)
387
signs[i] = speex_bits_unpack_unsigned(bits, 1);
390
ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
392
/* Compute decoded excitation */
393
for (i=0;i<nb_subvect;i++)
401
for (j=0;j<subvect_size;j++)
402
exc[subvect_size*i+j]=SHL((spx_word32_t)shape_cb[ind[i]*subvect_size+j],SIG_SHIFT-5);
404
for (j=0;j<subvect_size;j++)
405
exc[subvect_size*i+j]=-SHL((spx_word32_t)shape_cb[ind[i]*subvect_size+j],SIG_SHIFT-5);
408
for (j=0;j<subvect_size;j++)
409
exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];
414
void noise_codebook_quant(
415
spx_sig_t target[], /* target vector */
416
spx_coef_t ak[], /* LPCs for this subframe */
417
spx_coef_t awk1[], /* Weighted LPCs for this subframe */
418
spx_coef_t awk2[], /* Weighted LPCs for this subframe */
419
const void *par, /* Codebook/search parameters*/
420
int p, /* number of LPC coeffs */
421
int nsf, /* number of samples in subframe */
430
spx_sig_t *tmp=PUSH(stack, nsf, spx_sig_t);
431
residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack);
441
void noise_codebook_unquant(
443
const void *par, /* non-overlapping codebook */
444
int nsf, /* number of samples in subframe */
449
speex_rand_vec(1, exc, nsf);