ref: 791cfe1f0a4e09a0639ca30a2be1ae68974413a2
parent: 9f89cab6ecddd1da9ba5a964322d45b796e38485
author: Jean-Marc Valin <[email protected]>
date: Fri May 21 11:44:06 EDT 2010
Increasing the temporal resolution of transients Apply a one-level Haar transform (or Hadamard) on each short MDCT to nearly double the time-domain resolution.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -452,6 +452,19 @@
RESTORE_STACK;
}
+static void haar1(celt_norm *X, int N0, int stride)
+{
+ int i, j;
+ N0 >>= 1;
+ for (i=0;i<stride;i++)
+ for (j=0;j<N0;j++)
+ {
+ celt_norm tmp = X[stride*2*j+i];
+ X[stride*2*j+i] = MULT16_16_Q15(QCONST16(.7070678f,15), X[stride*2*j+i] + X[stride*(2*j+1)+i]);
+ X[stride*(2*j+1)+i] = MULT16_16_Q15(QCONST16(.7070678f,15), tmp - X[stride*(2*j+1)+i]);
+ }
+}
+
/* This function is responsible for encoding and decoding a band for both
the mono and stereo case. Even in the mono case, it can split the band
in two and transmit the energy difference with the two half-bands. It
@@ -466,19 +479,33 @@
int imid=0, iside=0;
int N0=N;
int N_B=N;
+ int N_B0;
int spread0=spread;
+ int do_haar = 0;
if (spread)
N_B /= spread;
+ N_B0 = N_B;
split = stereo = Y != NULL;
if (!stereo && spread>1 && level==0)
{
+ if ((N_B&1) == 0)
+ {
+ spread <<= 1;
+ N_B >>= 1;
+ do_haar = 1;
+ if (encode)
+ haar1(X, N_B0, spread0);
+ if (lowband)
+ haar1(lowband, N_B0, spread0);
+ spread0 = spread;
+ }
if (encode)
- deinterleave_vector(X, N_B, spread);
+ deinterleave_vector(X, N_B, spread0);
if (lowband)
- deinterleave_vector(lowband, N_B, spread);
+ deinterleave_vector(lowband, N_B, spread0);
}
/* If we need more than 32 bits, try splitting the band in two. */
@@ -752,6 +779,12 @@
interleave_vector(X, N_B, spread0);
if (lowband)
interleave_vector(lowband, N_B, spread0);
+ if (do_haar)
+ {
+ haar1(X, N_B0, spread0>>1);
+ if (lowband)
+ haar1(lowband, N_B0, spread0>>1);
+ }
}
if (lowband_out && !stereo)