ref: 9b4ed5e2907d632659193766e02eaf98db9aff4e
parent: 128d0c1cb7832ebb23b847192fcd839d5d5c090e
author: Jean-Marc Valin <[email protected]>
date: Wed Nov 24 13:01:20 EST 2010
Implementing intensity stereo. There's no explicit signaling for it yet.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -490,6 +490,7 @@
int B0=B;
int time_divide=0;
int recombine=0;
+ int inv = 0;
celt_word16 mid=0, side=0;
N_B /= B;
@@ -599,32 +600,18 @@
/* Decide on the resolution to give to the split parameter theta */
offset = ((m->logN[i]+(LM<<BITRES))>>1) - (stereo ? QTHETA_OFFSET_STEREO : QTHETA_OFFSET);
qn = compute_qn(N, b, offset, stereo);
-
qalloc = 0;
+ if (stereo && b<12*N && i>=9)
+ qn = 1;
if (qn!=1)
{
if (encode)
{
- if (stereo)
- stereo_split(X, Y, N);
-
- mid = vector_norm(X, N);
- side = vector_norm(Y, N);
- /* TODO: Renormalising X and Y *may* help fixed-point a bit at very high rate.
- Let's do that at higher complexity */
- /*mid = renormalise_vector(X, Q15ONE, N, 1);
- side = renormalise_vector(Y, Q15ONE, N, 1);*/
-
/* theta is the atan() of the ratio between the (normalized)
side and mid. With just that parameter, we can re-scale both
mid and side because we know that 1) they have unit norm and
2) they are orthogonal. */
- #ifdef FIXED_POINT
- /* 0.63662 = 2/pi */
- itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
- #else
- itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));
- #endif
+ itheta = stereo_itheta(X, Y, stereo, N);
itheta = (itheta*qn+8192)>>14;
}
@@ -674,9 +661,31 @@
qalloc = log2_frac(ft,BITRES) - log2_frac(fs,BITRES) + 1;
}
itheta = (celt_int32)itheta*16384/qn;
- } else {
- if (stereo && encode)
+ if (encode && stereo)
+ stereo_split(X, Y, N);
+ /* TODO: Renormalising X and Y *may* help fixed-point a bit at very high rate.
+ Let's do that at higher complexity */
+ } else if (stereo) {
+ if (encode)
+ {
+ inv = itheta > 8192;
+ if (inv)
+ {
+ int j;
+ for (j=0;j<N;j++)
+ Y[j] = -Y[j];
+ }
intensity_stereo(m, X, Y, bandE, i, N);
+ }
+ if (b>2<<BITRES)
+ {
+ if (encode)
+ ec_enc_bit_prob(ec, inv, 16384);
+ else
+ inv = ec_dec_bit_prob(ec, 16384);
+ qalloc = 1<<BITRES;
+ } else
+ inv = 0;
}
if (itheta == 0)
@@ -847,6 +856,12 @@
{
if (N!=2)
stereo_merge(X, Y, mid, side, N);
+ if (inv)
+ {
+ int j;
+ for (j=0;j<N;j++)
+ Y[j] = -Y[j];
+ }
} else if (level == 0)
{
int k;
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -338,19 +338,6 @@
RESTORE_STACK;
}
-celt_word16 vector_norm(const celt_norm *X, int N)
-{
- int i;
- celt_word32 E = EPSILON;
- const celt_norm *xptr = X;
- for (i=0;i<N;i++)
- {
- E = MAC16_16(E, *xptr, *xptr);
- xptr++;
- }
- return celt_sqrt(E);
-}
-
void renormalise_vector(celt_norm *X, int N, celt_word16 gain)
{
int i;
@@ -381,3 +368,42 @@
/*return celt_sqrt(E);*/
}
+int stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N)
+{
+ int i;
+ int itheta;
+ celt_word16 mid, side;
+ celt_word32 Emid, Eside;
+
+ Emid = Eside = EPSILON;
+ if (stereo)
+ {
+ for (i=0;i<N;i++)
+ {
+ celt_norm m, s;
+ m = X[i]+Y[i];
+ s = X[i]-Y[i];
+ Emid = MAC16_16(Emid, m, m);
+ Eside = MAC16_16(Eside, s, s);
+ }
+ } else {
+ for (i=0;i<N;i++)
+ {
+ celt_norm m, s;
+ m = X[i];
+ s = Y[i];
+ Emid = MAC16_16(Emid, m, m);
+ Eside = MAC16_16(Eside, s, s);
+ }
+ }
+ mid = celt_sqrt(Emid);
+ side = celt_sqrt(Eside);
+#ifdef FIXED_POINT
+ /* 0.63662 = 2/pi */
+ itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
+#else
+ itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));
+#endif
+
+ return itheta;
+}
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -66,6 +66,6 @@
void renormalise_vector(celt_norm *X, int N, celt_word16 gain);
-celt_word16 vector_norm(const celt_norm *X, int N);
+int stereo_itheta(celt_norm *X, celt_norm *Y, int stereo, int N);
#endif /* VQ_H */