Skip to content
Snippets Groups Projects
Commit 0d227d86 authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Got the intra-band prediction/copy to work correctly with

pulse spreading (and to work at all).
parent 97252d03
No related branches found
No related tags found
No related merge requests found
......@@ -207,27 +207,27 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, ec_enc *enc)
for (i=0;i<m->nbEBands;i++)
{
int q;
float theta, n;
q = m->nbPulses[i];
if (q>0) {
float theta, n;
n = sqrt(B*(eBands[i+1]-eBands[i]));
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(m->nbPulses[i]));
n = sqrt(B*(eBands[i+1]-eBands[i]));
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(m->nbPulses[i]));
if (q<=0) {
q = -q;
intra_prediction(X+B*eBands[i], W+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], enc);
}
if (q != 0)
{
exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, -1, B, 8);
exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, -1, B, 8);
alg_quant(X+B*eBands[i], W+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], 0.7, enc);
exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, 1, B, 8);
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
//printf ("%f ", log2(ncwrs64(B*(eBands[i+1]-eBands[i]), q))/(B*(eBands[i+1]-eBands[i])));
//printf ("%f ", log2(ncwrs64(B*(eBands[i+1]-eBands[i]), q)));
} else {
float n = sqrt(B*(eBands[i+1]-eBands[i]));
copy_quant(X+B*eBands[i], W+B*eBands[i], B*(eBands[i+1]-eBands[i]), -q, norm, B, eBands[i], enc);
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
//printf ("%f ", (1+log2(eBands[i]-(eBands[i+1]-eBands[i]))+log2(ncwrs64(B*(eBands[i+1]-eBands[i]), -q)))/(B*(eBands[i+1]-eBands[i])));
//printf ("%f ", (1+log2(eBands[i]-(eBands[i+1]-eBands[i]))+log2(ncwrs64(B*(eBands[i+1]-eBands[i]), -q))));
}
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
//printf ("%f ", log2(ncwrs64(B*(eBands[i+1]-eBands[i]), q))/(B*(eBands[i+1]-eBands[i])));
//printf ("%f ", log2(ncwrs64(B*(eBands[i+1]-eBands[i]), q)));
}
//printf ("\n");
for (i=B*eBands[m->nbEBands];i<B*eBands[m->nbEBands+1];i++)
......@@ -244,40 +244,25 @@ void unquant_bands(const CELTMode *m, float *X, float *P, ec_dec *dec)
for (i=0;i<m->nbEBands;i++)
{
int q;
float theta, n;
q = m->nbPulses[i];
if (q>0) {
float theta, n;
n = sqrt(B*(eBands[i+1]-eBands[i]));
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(m->nbPulses[i]));
n = sqrt(B*(eBands[i+1]-eBands[i]));
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(m->nbPulses[i]));
if (q<=0) {
q = -q;
intra_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], dec);
}
if (q != 0)
{
exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, -1, B, 8);
alg_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], 0.7, dec);
exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, 1, B, 8);
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
} else {
float n = sqrt(B*(eBands[i+1]-eBands[i]));
for (j=B*eBands[i];j<B*eBands[i+1];j++)
X[j] = 0;
copy_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), -q, norm, B, eBands[i], dec);
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
}
for (j=B*eBands[i];j<B*eBands[i+1];j++)
norm[j] = X[j] * n;
}
for (i=B*eBands[m->nbEBands];i<B*eBands[m->nbEBands+1];i++)
X[i] = 0;
}
void band_rotation(const CELTMode *m, float *X, int dir)
{
return;
int i, B;
const int *eBands = m->eBands;
B = m->nbMdctBlocks*m->nbChannels;
for (i=0;i<m->nbEBands;i++)
{
float theta;
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(m->nbPulses[i]));
exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, dir, B, 8);
}
//printf ("\n");
}
......@@ -51,6 +51,4 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, ec_enc *enc);
void unquant_bands(const CELTMode *m, float *X, float *P, ec_dec *dec);
void band_rotation(const CELTMode *m, float *X, int dir);
#endif /* BANDS_H */
......@@ -220,10 +220,49 @@ void alg_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc *
}
static const float pg[5] = {1.f, .6f, .45f, 0.35f, 0.25f};
void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
{
int i;
celt_uint64_t id;
int comb[K];
int signs[K];
int iy[N];
float y[N];
float Rpp=0, Ryp=0, Ryy=0;
float g;
/* Finds the right offset into Y and copy it */
void copy_quant(float *x, float *W, int N, int K, float *Y, int B, int N0, ec_enc *enc)
id = ec_dec_uint64(dec, ncwrs64(N, K));
cwrsi64(N, K, id, comb, signs);
comb2pulse(N, K, iy, comb, signs);
//for (i=0;i<N;i++)
// printf ("%d ", iy[i]);
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] - alpha*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];
}
static const float pg[11] = {1.f, .75f, .65f, 0.6f, 0.6f, .6f, .55f, .55f, .5f, .5f, .5f};
void intra_prediction(float *x, float *W, int N, int K, float *Y, float *P, int B, int N0, ec_enc *enc)
{
int i,j;
int best=0;
......@@ -260,77 +299,35 @@ void copy_quant(float *x, float *W, int N, int K, float *Y, int B, int N0, ec_en
ec_enc_uint(enc,sign,2);
ec_enc_uint(enc,best/B,N0-N/B);
//printf ("%d %f\n", best, best_score);
if (K==0)
float pred_gain;
if (K>10)
pred_gain = pg[10];
else
pred_gain = pg[K];
E = 1e-10;
for (j=0;j<N;j++)
{
P[j] = s*Y[best+j];
E += P[j]*P[j];
}
E = pred_gain/sqrt(E);
for (j=0;j<N;j++)
P[j] *= E;
if (K>0)
{
E = 1e-10;
for (j=0;j<N;j++)
{
x[j] = s*Y[best+j];
E += x[j]*x[j];
}
E = 1/sqrt(E);
for (j=0;j<N;j++)
x[j] *= E;
x[j] -= P[j];
} else {
float P[N];
float pred_gain;
if (K>4)
pred_gain = .5;
else
pred_gain = pg[K];
E = 1e-10;
for (j=0;j<N;j++)
{
P[j] = s*Y[best+j];
E += P[j]*P[j];
}
E = .8/sqrt(E);
for (j=0;j<N;j++)
P[j] *= E;
alg_quant(x, W, N, K, P, 0, enc);
x[j] = P[j];
}
}
//printf ("quant ");
//for (j=0;j<N;j++) printf ("%f ", P[j]);
void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
{
int i;
celt_uint64_t id;
int comb[K];
int signs[K];
int iy[N];
float y[N];
float Rpp=0, Ryp=0, Ryy=0;
float g;
id = ec_dec_uint64(dec, ncwrs64(N, K));
cwrsi64(N, K, id, comb, signs);
comb2pulse(N, K, iy, comb, signs);
//for (i=0;i<N;i++)
// printf ("%d ", iy[i]);
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] - alpha*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];
}
void copy_unquant(float *x, int N, int K, float *Y, int B, int N0, ec_dec *dec)
void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec_dec *dec)
{
int j;
int sign;
......@@ -346,33 +343,23 @@ void copy_unquant(float *x, int N, int K, float *Y, int B, int N0, ec_dec *dec)
best = B*ec_dec_uint(dec, N0-N/B);
//printf ("%d %d ", sign, best);
float pred_gain;
if (K>10)
pred_gain = pg[10];
else
pred_gain = pg[K];
E = 1e-10;
for (j=0;j<N;j++)
{
P[j] = s*Y[best+j];
E += P[j]*P[j];
}
E = pred_gain/sqrt(E);
for (j=0;j<N;j++)
P[j] *= E;
if (K==0)
{
E = 1e-10;
for (j=0;j<N;j++)
{
x[j] = s*Y[best+j];
E += x[j]*x[j];
}
E = 1/sqrt(E);
for (j=0;j<N;j++)
x[j] *= E;
} else {
float P[N];
float pred_gain;
if (K>4)
pred_gain = .5;
else
pred_gain = pg[K];
E = 1e-10;
for (j=0;j<N;j++)
{
P[j] = s*Y[best+j];
E += P[j]*P[j];
}
E = .8/sqrt(E);
for (j=0;j<N;j++)
P[j] *= E;
alg_unquant(x, N, K, P, 0, dec);
x[j] = P[j];
}
}
......@@ -36,15 +36,15 @@
#include "entdec.h"
/* Algebraic pulse-base quantiser. The signal x is replaced by the sum of the pitch
/* Algebraic pulse-based 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_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc *enc);
void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec);
/* Finds the right offset into Y and copy it */
void copy_quant(float *x, float *W, int N, int K, float *Y, int B, int N0, ec_enc *enc);
void intra_prediction(float *x, float *W, int N, int K, float *Y, float *P, int B, int N0, ec_enc *enc);
void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec_dec *dec);
void copy_unquant(float *x, int N, int K, float *Y, int B, int N0, ec_dec *dec);
#endif /* VQ_H */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment