ref: 0e20ca096970ae9c515a35ae72fd637219241cf5
parent: 8f0f4b942166bf9385319fdbbde390e5a21e0f6a
author: Jean-Marc Valin <[email protected]>
date: Mon Feb 11 10:33:53 EST 2008
Enabling "plain folding" in case we don't even have enough bits for intra-frame prediction
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -259,11 +259,17 @@
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(q));
/* If pitch isn't available, use intra-frame prediction */
- if (eBands[i] >= m->pitchEnd)
- 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)
+ if (eBands[i] >= m->pitchEnd || q<=0)
{
+ q -= 1;
+ if (q<0)
+ intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i]);
+ else
+ 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);
@@ -305,10 +311,16 @@
theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(q));
/* If pitch isn't available, use intra-frame prediction */
- if (eBands[i] >= m->pitchEnd)
- 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)
+ if (eBands[i] >= m->pitchEnd || q<=0)
+ {
+ q -= 1;
+ if (q<0)
+ intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i]);
+ else
+ 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);
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -118,19 +118,27 @@
for (j=0;j<MAX_PULSES;j++)
{
int done = 0;
- alloc->bits[i][j] = log2_frac64(ncwrs64(N, j),BITRES);
- /* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
- if (alloc->bits[i][j] > (60<<BITRES))
- done = 1;
- /* Add the intra-frame prediction bits */
+ int pulses = j;
+ /* For bands where there's no pitch, id 1 corresponds to intra prediction
+ with no pulse. id 2 means intra prediction with one pulse, and so on.*/
if (eBands[i] >= m->pitchEnd)
- {
- int max_pos = 2*eBands[i]-eBands[i+1];
- if (max_pos > 32)
- max_pos = 32;
- alloc->bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
+ pulses -= 1;
+ if (pulses < 0)
+ alloc->bits[i][j] = 0;
+ else {
+ alloc->bits[i][j] = log2_frac64(ncwrs64(N, pulses),BITRES);
+ /* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
+ if (alloc->bits[i][j] > (60<<BITRES))
+ done = 1;
+ /* Add the intra-frame prediction bits */
+ if (eBands[i] >= m->pitchEnd)
+ {
+ int max_pos = 2*eBands[i]-eBands[i+1];
+ if (max_pos > 32)
+ max_pos = 32;
+ alloc->bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
+ }
}
- /* We could just update rev_bits here */
if (done)
break;
}
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -66,9 +66,9 @@
}
bytes_per_packet = atoi(argv[2]);
- if (bytes_per_packet < 20 || bytes_per_packet > 120)
+ if (bytes_per_packet < 15 || bytes_per_packet > 120)
{
- fprintf (stderr, "bytes per packet must be between 20 and 120\n");
+ fprintf (stderr, "bytes per packet must be between 15 and 120\n");
return 1;
}
inFile = argv[3];
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -372,3 +372,22 @@
x[j] = P[j];
}
}
+
+void intra_fold(float *x, int N, int K, float *Y, float *P, int B, int N0)
+{
+ int j;
+ float E;
+
+ E = 1e-10;
+ for (j=0;j<N;j++)
+ {
+ P[j] = Y[j];
+ E += P[j]*P[j];
+ }
+ E = 1.f/sqrt(E);
+ for (j=0;j<N;j++)
+ P[j] *= E;
+ for (j=0;j<N;j++)
+ x[j] = P[j];
+}
+
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -75,4 +75,6 @@
void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec_dec *dec);
+void intra_fold(float *x, int N, int K, float *Y, float *P, int B, int N0);
+
#endif /* VQ_H */