Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/speex.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>2002-03-14 10:08:48 +0300
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>2002-03-14 10:08:48 +0300
commitafc40879ee2560ad9e7b2da23be6b7472e2e7b6f (patch)
tree11d7c7b880c847f649d5d45110ea64db5dc7318d /libspeex
parentab9dbc47c097f93241e7f273d69f9da1f09f8ed6 (diff)
More cleanup in codebook search...
git-svn-id: http://svn.xiph.org/trunk/speex@3142 0101bb08-14d6-0310-b084-bc0e0c8e3800
Diffstat (limited to 'libspeex')
-rw-r--r--libspeex/Makefile.am8
-rw-r--r--libspeex/cb_search.c161
-rw-r--r--libspeex/cb_search.h19
-rw-r--r--libspeex/speex.c4
-rw-r--r--libspeex/vq.c42
-rw-r--r--libspeex/vq.h26
6 files changed, 166 insertions, 94 deletions
diff --git a/libspeex/Makefile.am b/libspeex/Makefile.am
index e393e00..00db952 100644
--- a/libspeex/Makefile.am
+++ b/libspeex/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in. -*-Makefile-*-
-# $Id: Makefile.am,v 1.10 2002/03/13 18:28:09 jmvalin Exp $
+# $Id: Makefile.am,v 1.11 2002/03/14 07:08:48 jmvalin Exp $
# Disable automatic dependency tracking if using other tools than gcc and gmake
#AUTOMAKE_OPTIONS = no-dependencies
@@ -21,7 +21,8 @@ libspeex_la_SOURCES = speex.c \
bits.c \
modes.c \
exc_table.c \
- exc_gains_table.c
+ exc_gains_table.c \
+ vq.c
include_HEADERS = speex.h \
bits.h \
@@ -33,7 +34,8 @@ noinst_HEADERS = lsp.h \
quant_lsp.h \
cb_search.h \
filters.h \
- stack_alloc.h
+ stack_alloc.h \
+ vq.h
libspeex_la_LDFLAGS = -release $(LT_RELEASE)
diff --git a/libspeex/cb_search.c b/libspeex/cb_search.c
index 47d9641..1c52137 100644
--- a/libspeex/cb_search.c
+++ b/libspeex/cb_search.c
@@ -34,10 +34,13 @@
#include "filters.h"
#include <math.h>
#include <stdio.h>
+#include "stack_alloc.h"
+#include "vq.h"
#define EXC_CB_SIZE 128
#define min(a,b) ((a) < (b) ? (a) : (b))
-extern float exc_gains_table[128][5];
+extern float exc_gains_table[];
+extern float exc_table[];
/*---------------------------------------------------------------------------*\
@@ -128,7 +131,14 @@ int nsf /* number of samples in subframe */
}
-
+split_cb_params split_cb_nb = {
+ 8, /*subvect_size*/
+ 5, /*nb_subvect*/
+ exc_table, /*shape_cb*/
+ 7, /*shape_bits*/
+ exc_gains_table, /*gain_cb*/
+ 8 /*gain_bits*/
+};
void split_cb_search(
@@ -136,43 +146,63 @@ float target[], /* target vector */
float ak[], /* LPCs for this subframe */
float awk1[], /* Weighted LPCs for this subframe */
float awk2[], /* Weighted LPCs for this subframe */
-float codebook[][8], /* non-overlapping codebook */
-int entries, /* number of entries to search */
-float *gain, /* gain of optimum entries */
-int *index, /* index of optimum entries */
+void *par, /* Codebook/search parameters*/
int p, /* number of LPC coeffs */
int nsf, /* number of samples in subframe */
float *exc,
-FrameBits *bits
+FrameBits *bits,
+float *stack
)
{
int i,j;
- float resp[EXC_CB_SIZE][8], E[EXC_CB_SIZE], Ee[EXC_CB_SIZE];
- float t[40], r[40], e[40];
- float gains[5];
- int ind[5];
- for (i=0;i<40;i++)
+ float *resp, *E, *Ee;
+ float *t, *r, *e;
+ float *gains;
+ int *ind;
+ float *shape_cb, *gain_cb;
+ int shape_cb_size, gain_cb_size, subvect_size, nb_subvect;
+ split_cb_params *params;
+
+ params = (split_cb_params *) par;
+ subvect_size = params->subvect_size;
+ nb_subvect = params->nb_subvect;
+ shape_cb_size = 1<<params->shape_bits;
+ shape_cb = params->shape_cb;
+ gain_cb_size = 1<<params->gain_bits;
+ gain_cb = params->gain_cb;
+ resp = PUSH(stack, shape_cb_size*8);
+ E = PUSH(stack, shape_cb_size);
+ Ee = PUSH(stack, shape_cb_size);
+ t = PUSH(stack, nsf);
+ r = PUSH(stack, nsf);
+ e = PUSH(stack, nsf);
+ gains = PUSH(stack, nb_subvect);
+ ind = (int*)PUSH(stack, nb_subvect);
+
+
+ for (i=0;i<nsf;i++)
t[i]=target[i];
- for (i=0;i<EXC_CB_SIZE;i++)
+ for (i=0;i<shape_cb_size;i++)
{
- residue_zero(codebook[i], awk1, resp[i], 8, p);
- syn_filt_zero(resp[i], ak, resp[i], 8, p);
- syn_filt_zero(resp[i], awk2, resp[i], 8,p);
+ float *res = resp+i*subvect_size;
+ residue_zero(shape_cb+i*subvect_size, awk1, res, 8, p);
+ syn_filt_zero(res, ak, res, 8, p);
+ syn_filt_zero(res, awk2, res, 8,p);
E[i]=0;
for(j=0;j<8;j++)
- E[i]+=resp[i][j]*resp[i][j];
+ E[i]+=res[j]*res[j];
Ee[i]=0;
for(j=0;j<8;j++)
- Ee[i]+=codebook[i][j]*codebook[i][j];
+ Ee[i]+=shape_cb[i*subvect_size+j]*shape_cb[i*subvect_size+j];
}
for (i=0;i<5;i++)
{
int best_index=0;
float g, corr, best_gain=0, score, best_score=-1;
- for (j=0;j<EXC_CB_SIZE;j++)
+ for (j=0;j<shape_cb_size;j++)
{
- corr=xcorr(resp[j],t+8*i,8);
+ corr=xcorr(resp+j*subvect_size,t+8*i,8);
score=corr*corr/(.001+E[j]);
g = corr/(.001+E[j]);
if (score>best_score)
@@ -182,48 +212,23 @@ FrameBits *bits
best_gain=corr/(.001+E[j]);
}
}
- frame_bits_pack(bits,best_index,7);
+ frame_bits_pack(bits,best_index,params->shape_bits);
if (best_gain>0)
frame_bits_pack(bits,0,1);
else
frame_bits_pack(bits,1,1);
ind[i]=best_index;
gains[i]=best_gain*Ee[ind[i]];
- if (0) { /* Simulating scalar quantization of the gain*/
- float sign=1;
- printf("before: %f\n", best_gain);
- if (best_gain<0)
- {
- sign=-1;
- }
- best_gain = fabs(best_gain)+.1;
- best_gain = log(best_gain);
- if (best_gain>8)
- best_gain=8;
- if (best_gain<0)
- best_gain=0;
- /*best_gain=.125*floor(8*best_gain+.5);*/
- best_gain=.25*floor(4*best_gain+.5);
- best_gain=sign*exp(best_gain);
- if (fabs(best_gain)<1.01)
- best_gain=0;
- printf("after: %f\n", best_gain);
- }
- printf ("search: %d %f %f %f\n", best_index, best_gain, best_gain*best_gain*E[best_index], best_score);
- for (j=0;j<40;j++)
+ for (j=0;j<nsf;j++)
e[j]=0;
for (j=0;j<8;j++)
- e[8*i+j]=best_gain*codebook[best_index][j];
- residue_zero(e, awk1, r, 40, p);
- syn_filt_zero(r, ak, r, 40, p);
- syn_filt_zero(r, awk2, r, 40,p);
- for (j=0;j<40;j++)
+ e[8*i+j]=best_gain*shape_cb[best_index*subvect_size+j];
+ residue_zero(e, awk1, r, nsf, p);
+ syn_filt_zero(r, ak, r, nsf, p);
+ syn_filt_zero(r, awk2, r, nsf,p);
+ for (j=0;j<nsf;j++)
t[j]-=r[j];
-
- /*FIXME: Should move that out of the loop if we are to vector-quantize the gains*/
- /*for (j=0;j<40;j++)
- exc[j]+=e[j];*/
}
{
@@ -254,50 +259,38 @@ FrameBits *bits
gains[i]*=max_gain;
frame_bits_pack(bits,max_index,3);
- if (max_index>2)
- {
- for (i=0;i<5;i++)
- printf ("%f ", gains[i]);
- printf ("cbgains: \n");
- }
/*Vector quantize gains[i]*/
- for (i=0;i<256;i++)
- {
- float dist=0;
- for (j=0;j<5;j++)
- dist += (exc_gains_table[i][j]-gains[j])*(exc_gains_table[i][j]-gains[j]);
- if (i==0 || dist<min_dist)
- {
- min_dist=dist;
- best_vq_index=i;
- }
- }
- frame_bits_pack(bits,best_vq_index,8);
+ best_vq_index = vq_index(gains, gain_cb, nb_subvect, gain_cb_size);
+ frame_bits_pack(bits,best_vq_index,params->gain_bits);
+
printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
-#if 1
+
+#if 1 /* If 0, the gains are not quantized */
for (i=0;i<5;i++)
- gains[i]= sign[i]*exc_gains_table[best_vq_index][i]/max_gain/(Ee[ind[i]]+.001);
+ gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001);
#else
for (i=0;i<5;i++)
gains[i]= sign[i]*gains[i]/max_gain/(Ee[ind[i]]+.001);
#endif
-
- printf ("unquant gains: ");
- for (i=0;i<5;i++)
- printf ("%f ", gains[i]);
- printf ("\n");
for (i=0;i<5;i++)
for (j=0;j<8;j++)
- exc[8*i+j]+=gains[i]*codebook[ind[i]][j];
+ exc[8*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];
}
- /*for (i=0;i<5;i++)
- printf ("%f ", gains[i]);
- printf ("cbgains: \n");*/
- /*TODO: Perform joint optimization of gains and quantization with prediction*/
+
+ /*TODO: Perform joint optimization of gains*/
- for (i=0;i<40;i++)
+ for (i=0;i<nsf;i++)
target[i]=t[i];
+
+ POP(stack);
+ POP(stack);
+ POP(stack);
+ POP(stack);
+ POP(stack);
+ POP(stack);
+ POP(stack);
+ POP(stack);
}
void split_cb_unquant(
@@ -330,7 +323,7 @@ FrameBits *bits
max_gain=exp(max_gain_ind+3.0);
for (i=0;i<5;i++)
- gains[i] = sign[i]*exc_gains_table[vq_gain_ind][i]*max_gain/Ee[i];
+ gains[i] = sign[i]*exc_gains_table[vq_gain_ind*5+i]*max_gain/Ee[i];
printf ("unquant gains: ");
for (i=0;i<5;i++)
diff --git a/libspeex/cb_search.h b/libspeex/cb_search.h
index 696f844..de0de11 100644
--- a/libspeex/cb_search.h
+++ b/libspeex/cb_search.h
@@ -36,19 +36,28 @@ int nsf /* number of samples in subframe */
);
+typedef struct split_cb_params {
+ int subvect_size;
+ int nb_subvect;
+ float *shape_cb;
+ int shape_bits;
+ float *gain_cb;
+ int gain_bits;
+} split_cb_params;
+
+extern split_cb_params split_cb_nb;
+
void split_cb_search(
float target[], /* target vector */
float ak[], /* LPCs for this subframe */
float awk1[], /* Weighted LPCs for this subframe */
float awk2[], /* Weighted LPCs for this subframe */
-float codebook[][8], /* overlapping codebook */
-int entries, /* number of entries to search */
-float *gain, /* gain of optimum entries */
-int *index, /* index of optimum entries */
+void *par, /* Codebook/search parameters*/
int p, /* number of LPC coeffs */
int nsf, /* number of samples in subframe */
float *exc,
-FrameBits *bits
+FrameBits *bits,
+float *stack
);
void split_cb_unquant(
diff --git a/libspeex/speex.c b/libspeex/speex.c
index 373607b..05a9798 100644
--- a/libspeex/speex.c
+++ b/libspeex/speex.c
@@ -327,8 +327,8 @@ void encode(EncState *st, float *in, FrameBits *bits)
#else
/* Perform a split-codebook search */
split_cb_search(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
- exc_table, 64, &gain[0], &pitch, st->lpcSize,
- st->subframeSize, exc, bits);
+ &split_cb_nb, st->lpcSize,
+ st->subframeSize, exc, bits, st->stack);
#endif
/* Compute weighted noise energy, SNR */
diff --git a/libspeex/vq.c b/libspeex/vq.c
new file mode 100644
index 0000000..d26b20a
--- /dev/null
+++ b/libspeex/vq.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2002 Jean-Marc Valin & David Rowe
+ File: vq.c
+ Vector quantization
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "vq.h"
+
+int vq_index(float *in, float *codebook, int len, int entries)
+{
+ int i,j;
+ float min_dist=0;
+ int best_index=0;
+ for (i=0;i<entries;i++)
+ {
+ float dist=0;
+ for (j=0;j<len;j++)
+ {
+ float tmp = in[j]-*codebook++;
+ dist += tmp*tmp;
+ }
+ if (i==0 || dist<min_dist)
+ {
+ min_dist=dist;
+ best_index=i;
+ }
+ }
+ return best_index;
+}
diff --git a/libspeex/vq.h b/libspeex/vq.h
new file mode 100644
index 0000000..2460bad
--- /dev/null
+++ b/libspeex/vq.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2002 Jean-Marc Valin & David Rowe
+ File: vq.h
+ Vector quantization
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef VQ_H
+#define VQ_H
+
+int vq_index(float *in, float *codebook, int len, int entries);
+
+
+#endif