ref: fc08d0a6d63a5453a8928bd5f77e30cf73f13073
parent: 269d40a5c0d99123c97499765024f469c28c3e38
author: Jean-Marc Valin <[email protected]>
date: Fri Dec 7 08:26:15 EST 2007
Algebraic codebook decoding (not tested yet)
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -160,7 +160,7 @@
q = m->nbPulses[i];
if (q>0) {
float n = sqrt(B*(eBands[i+1]-eBands[i]));
- alg_quant2(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], enc);
+ alg_quant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], enc);
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
//bits += log2(ncwrs(B*(eBands[i+1]-eBands[i]), q));
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -351,7 +351,7 @@
celt_free(st);
}
-int celt_decode(CELTDecoder *st, short *pcm)
+int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
{
int i, N, B;
N = st->block_size;
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -54,6 +54,6 @@
void celt_decoder_destroy(CELTDecoder *st);
-int celt_decode(CELTDecoder *st, short *pcm);
+int celt_decode(CELTDecoder *st, char *data, int len, short *pcm);
#endif /*CELT_H */
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -34,69 +34,11 @@
#include "cwrs.h"
#include "vq.h"
-/* Algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
- a combination of pulses such that its norm is still equal to 1 */
-void alg_quant(float *x, int N, int K, float *p)
-{
- float y[N];
- int i,j;
- float xy = 0;
- float yy = 0;
- float yp = 0;
- float Rpp=0;
- float gain=0;
- for (j=0;j<N;j++)
- Rpp += p[j]*p[j];
- for (i=0;i<N;i++)
- y[i] = 0;
-
- for (i=0;i<K;i++)
- {
- int best_id=0;
- float max_val=-1e10;
- float best_xy=0, best_yy=0, best_yp = 0;
- for (j=0;j<N;j++)
- {
- float tmp_xy, tmp_yy, tmp_yp;
- float score;
- float g;
- tmp_xy = xy + fabs(x[j]);
- tmp_yy = yy + 2*fabs(y[j]) + 1;
- if (x[j]>0)
- tmp_yp = yp + p[j];
- else
- tmp_yp = yp - p[j];
- g = (sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)/tmp_yy;
- score = 2*g*tmp_xy - g*g*tmp_yy;
- if (score>max_val)
- {
- max_val = score;
- best_id = j;
- best_xy = tmp_xy;
- best_yy = tmp_yy;
- best_yp = tmp_yp;
- gain = g;
- }
- }
- xy = best_xy;
- yy = best_yy;
- yp = best_yp;
- if (x[best_id]>0)
- y[best_id] += 1;
- else
- y[best_id] -= 1;
- }
-
- for (i=0;i<N;i++)
- x[i] = p[i]+gain*y[i];
-
-}
-
/* Improved algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
a combination of pulses such that its norm is still equal to 1. The only difference with
the quantiser above is that the search is more complete. */
-void alg_quant2(float *x, int N, int K, float *p, ec_enc *enc)
+void alg_quant(float *x, int N, int K, float *p, ec_enc *enc)
{
int L = 5;
//float tata[200];
@@ -117,6 +59,8 @@
for (j=0;j<N;j++)
Rpp += p[j]*p[j];
+ //if (Rpp>.01)
+ // alpha = (1-sqrt(1-Rpp))/Rpp;
for (j=0;j<N;j++)
Rxp += x[j]*p[j];
for (m=0;m<L;m++)
@@ -244,23 +188,6 @@
ec_enc_uint(enc,icwrs(N, K, comb, signs),ncwrs(N, K));
}
-/* Just replace the band with noise of unit energy */
-void noise_quant(float *x, int N, int K, float *p)
-{
- int i;
- float E = 1e-10;
- for (i=0;i<N;i++)
- {
- x[i] = (rand()%1000)/500.-1;
- E += x[i]*x[i];
- }
- E = 1./sqrt(E);
- for (i=0;i<N;i++)
- {
- x[i] *= E;
- }
-}
-
static const float pg[5] = {1.f, .82f, .75f, 0.7f, 0.6f};
/* Finds the right offset into Y and copy it */
@@ -321,6 +248,46 @@
E = .8/sqrt(E);
for (j=0;j<N;j++)
P[j] *= E;
- alg_quant2(x, N, K, P, enc);
+ alg_quant(x, N, K, P, enc);
}
}
+
+void alg_unquant(float *x, int N, int K, float *p, ec_dec *dec)
+{
+ int i;
+ unsigned int id;
+ int comb[K];
+ int signs[K];
+ int iy[N];
+ float y[N];
+ float alpha = .9;
+ float Rpp=0, Ryp=0, Ryy=0;
+ float g;
+
+ id = ec_dec_uint(dec, ncwrs(N, K));
+ cwrsi(N, K, id, comb, signs);
+ comb2pulse(N, K, iy, comb, signs);
+
+ for (i=0;i<N;i++)
+ Rpp += p[i]*p[i];
+
+ for (i=0;i<N;i++)
+ Ryp += iy[i]*p[i];
+
+ for (i=0;i<N;i++)
+ y[i] = iy[i] - Ryp*p[i];
+
+ /* Recompute after the projection (I think it's right) */
+ Ryp = 0;
+ for (i=0;i<N;i++)
+ Ryp += y[i]*p[i];
+
+ for (i=0;i<N;i++)
+ Ryy += y[i]*y[i];
+
+ g = (sqrt(Ryp*Ryp + Ryy - Ryy*Rpp) - Ryp)/Ryy;
+
+ for (i=0;i<N;i++)
+ x[i] = p[i] + g*y[i];
+}
+
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -33,18 +33,15 @@
#define VQ_H
#include "entenc.h"
+#include "entdec.h"
-/* Algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
- a combination of pulses such that its norm is still equal to 1 */
-void alg_quant(float *x, int N, int K, float *p);
-/* Improved algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
+/* Algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
a combination of pulses such that its norm is still equal to 1. The only difference with
the quantiser above is that the search is more complete. */
-void alg_quant2(float *x, int N, int K, float *p, ec_enc *enc);
+void alg_quant(float *x, int N, int K, float *p, ec_enc *enc);
-/* Just replace the band with noise of unit energy */
-void noise_quant(float *x, int N, int K, float *p);
+void alg_unquant(float *x, int N, int K, float *p, ec_dec *dec);
/* Finds the right offset into Y and copy it */
void copy_quant(float *x, int N, int K, float *Y, int B, int N0, ec_enc *enc);