diff --git a/libcelt/bands.c b/libcelt/bands.c index 737c064b62619f6667dd4a53ada839733f37ebdb..ac2703f2832284ea94bd6eef6adb8b02fbe87a4a 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -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"); -} diff --git a/libcelt/bands.h b/libcelt/bands.h index 5a195764786f555ef36910f852b2d6009cfc35b2..a7fc04fba06af45f17aa74b2c423ba26c16280b6 100644 --- a/libcelt/bands.h +++ b/libcelt/bands.h @@ -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 */ diff --git a/libcelt/vq.c b/libcelt/vq.c index 46899c0268c766b3a73a9b57a7185b132a4fc684..9dbb108fc68dccfa22e91c387442e0c4ad5e6a4a 100644 --- a/libcelt/vq.c +++ b/libcelt/vq.c @@ -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]; } } diff --git a/libcelt/vq.h b/libcelt/vq.h index 2e4f5e010291a1fdc0468adfe63578e70f6a8a08..41fcb2374ce3b5f5ab9fb835cea442e5167b4086 100644 --- a/libcelt/vq.h +++ b/libcelt/vq.h @@ -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 */