ref: cae30df09ade8ea53b0722024d627c0a12fc7f1a
parent: 4aa1b8df26d36867c87ddb7c35f84adb83721780
author: Jean-Marc Valin <[email protected]>
date: Thu May 20 20:26:03 EDT 2010
Getting rid of PVQ-level split Adding one more level of band splitting so that splitting at the PVQ encoding level is no longer necessary.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -316,9 +316,7 @@
}
}
-#ifndef DISABLE_STEREO
-
-static void stereo_band_mix(const CELTMode *m, celt_norm *X, celt_norm *Y, const celt_ener *bank, int stereo_mode, int bandID, int dir, int M)
+static void stereo_band_mix(const CELTMode *m, celt_norm *X, celt_norm *Y, const celt_ener *bank, int stereo_mode, int bandID, int dir, int N)
{
int i = bandID;
const celt_int16 *eBands = m->eBands;
@@ -341,7 +339,7 @@
a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
a2 = dir*DIV32_16(SHL32(EXTEND32(right),14),norm);
}
- for (j=0;j<M*eBands[i+1]-M*eBands[i];j++)
+ for (j=0;j<N;j++)
{
celt_norm r, l;
l = X[j];
@@ -352,8 +350,6 @@
}
-#endif /* DISABLE_STEREO */
-
int folding_decision(const CELTMode *m, celt_norm *X, celt_word16 *average, int *last_decision, int _C, int M)
{
int i, c, N0;
@@ -439,12 +435,15 @@
split = stereo = Y != NULL;
/* If we need more than 32 bits, try splitting the band in two. */
- if (!stereo && LM>0 && !fits_in32(N, get_pulses(bits2pulses(m, m->bits[LM][i], N, b))))
+ if (!stereo && LM != -1 && !fits_in32(N, get_pulses(bits2pulses(m, m->bits[LM][i], N, b))))
{
- N >>= 1;
- Y = X+N;
- split = 1;
- LM -= 1;
+ if (LM>0 || (N&1)==0)
+ {
+ N >>= 1;
+ Y = X+N;
+ split = 1;
+ LM -= 1;
+ }
}
if (split)
@@ -468,7 +467,7 @@
if (encode)
{
if (stereo)
- stereo_band_mix(m, X, Y, bandE, qb==0, i, 1, 1<<LM);
+ stereo_band_mix(m, X, Y, bandE, qb==0, i, 1, N);
mid = renormalise_vector(X, Q15ONE, N, 1);
side = renormalise_vector(Y, Q15ONE, N, 1);
@@ -644,10 +643,12 @@
}
} else {
- /* This is the basis no-split case */
+ /* This is the basic no-split case */
q = bits2pulses(m, m->bits[LM][i], N, b);
curr_bits = pulses2bits(m->bits[LM][i], N, q);
*remaining_bits -= curr_bits;
+
+ /* Ensures we can never bust the budget */
while (*remaining_bits < 0 && q > 0)
{
*remaining_bits += curr_bits;
@@ -655,6 +656,11 @@
curr_bits = pulses2bits(m->bits[LM][i], N, q);
*remaining_bits -= curr_bits;
}
+
+ /* Making sure we will *never* need more than 32 bits for the PVQ */
+ while (!fits_in32(N, get_pulses(q)))
+ q--;
+
if (encode)
alg_quant(X, N, q, spread, lowband, resynth, ec);
else
@@ -746,7 +752,7 @@
if (resynth && _Y != NULL)
{
- stereo_band_mix(m, X, Y, bandE, 0, i, -1, M);
+ stereo_band_mix(m, X, Y, bandE, 0, i, -1, N);
renormalise_vector(X, Q15ONE, N, 1);
renormalise_vector(Y, Q15ONE, N, 1);
}
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -141,15 +141,6 @@
*error = CELT_INVALID_MODE;
return NULL;
}
-#ifdef DISABLE_STEREO
- if (channels > 1)
- {
- celt_warning("Stereo support was disable from this build");
- if (error)
- *error = CELT_BAD_ARG;
- return NULL;
- }
-#endif
if (channels < 0 || channels > 2)
{
@@ -1217,15 +1208,6 @@
*error = CELT_INVALID_MODE;
return NULL;
}
-#ifdef DISABLE_STEREO
- if (channels > 1)
- {
- celt_warning("Stereo support was disable from this build");
- if (error)
- *error = CELT_BAD_ARG;
- return NULL;
- }
-#endif
if (channels < 0 || channels > 2)
{
--- a/libcelt/cwrs.c
+++ b/libcelt/cwrs.c
@@ -854,21 +854,10 @@
void encode_pulses(int *_y, int N, int K, ec_enc *enc)
{
- if (K==0) {
- } else if(fits_in32(N,K))
- {
- encode_pulses32(N, K, _y, enc);
- } else {
- int i;
- int count=0;
- int split;
- split = (N+1)/2;
- for (i=0;i<split;i++)
- count += abs(_y[i]);
- ec_enc_uint(enc,count,K+1);
- encode_pulses(_y, split, count, enc);
- encode_pulses(_y+split, N-split, K-count, enc);
- }
+ if (K==0)
+ return;
+ celt_assert(fits_in32(N,K));
+ encode_pulses32(N, K, _y, enc);
}
static inline void decode_pulses32(int _n,int _k,int *_y,ec_dec *_dec){
@@ -900,14 +889,9 @@
int i;
for (i=0;i<N;i++)
_y[i] = 0;
- } else if(fits_in32(N,K))
+ } else
{
+ celt_assert (fits_in32(N,K));
decode_pulses32(N, K, _y, dec);
- } else {
- int split;
- int count = ec_dec_uint(dec,K+1);
- split = (N+1)/2;
- decode_pulses(_y, split, count, dec);
- decode_pulses(_y+split, N-split, K-count, dec);
}
}
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -380,9 +380,15 @@
#endif
mode->window = window;
+ mode->bits = mode->_bits+1;
for (i=0;(1<<i)<=mode->nbShortMdcts;i++)
- mode->bits[i] = (const celt_int16 **)compute_alloc_cache(mode, 1, 1<<i);
- if (mode->bits==NULL)
+ {
+ mode->bits[i] = (const celt_int16 **)compute_alloc_cache(mode, 1<<i);
+ if (mode->bits[i]==NULL)
+ goto failure;
+ }
+ mode->bits[-1] = (const celt_int16 **)compute_alloc_cache(mode, 0);
+ if (mode->bits[-1]==NULL)
goto failure;
logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
@@ -459,6 +465,19 @@
}
celt_free((celt_int16**)mode->bits[m]);
}
+ if (mode->bits[-1]!=NULL)
+ {
+ for (i=0;i<mode->nbEBands;i++)
+ {
+ if (mode->bits[-1][i] != prevPtr)
+ {
+ prevPtr = mode->bits[-1][i];
+ celt_free((int*)mode->bits[-1][i]);
+ }
+ }
+ }
+ celt_free((celt_int16**)mode->bits[-1]);
+
celt_free((celt_int16*)mode->eBands);
celt_free((celt_int16*)mode->allocVectors);
--- a/libcelt/modes.h
+++ b/libcelt/modes.h
@@ -40,7 +40,7 @@
#include "mdct.h"
#include "pitch.h"
-#define MAX_CONFIG_SIZES 4
+#define MAX_CONFIG_SIZES 5
#define CELT_BITSTREAM_VERSION 0x8000000c
@@ -93,7 +93,8 @@
int nbAllocVectors; /**< Number of lines in the matrix below */
const celt_int16 *allocVectors; /**< Number of bits in each band for several rates */
- const celt_int16 * const *(bits[MAX_CONFIG_SIZES]); /**< Cache for pulses->bits mapping in each band */
+ const celt_int16 * const **bits;
+ const celt_int16 * const *(_bits[MAX_CONFIG_SIZES]); /**< Cache for pulses->bits mapping in each band */
/* Stuff that could go in the {en,de}coder, but we save space this way */
mdct_lookup mdct[MAX_CONFIG_SIZES];
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -46,7 +46,7 @@
#ifndef STATIC_MODES
-celt_int16 **compute_alloc_cache(CELTMode *m, int C, int M)
+celt_int16 **compute_alloc_cache(CELTMode *m, int M)
{
int i, prevN;
int error = 0;
@@ -60,9 +60,18 @@
prevN = -1;
for (i=0;i<m->nbEBands;i++)
{
- int N = C*M*(eBands[i+1]-eBands[i]);
- if (N == prevN && M*eBands[i] < m->pitchEnd)
+ int N;
+ if (M>0)
+ N = M*(eBands[i+1]-eBands[i]);
+ else
+ N = (eBands[i+1]-eBands[i])>>1;
+ if (N==0)
{
+ bits[i] = NULL;
+ continue;
+ }
+ if (N == prevN)
+ {
bits[i] = bits[i-1];
} else {
bits[i] = celt_alloc(MAX_PSEUDO*sizeof(celt_int16));
@@ -85,14 +94,14 @@
{
for (i=0;i<m->nbEBands;i++)
{
- if (bits[i] != prevPtr)
+ if (bits[i] != prevPtr && bits[i] != NULL)
{
prevPtr = bits[i];
celt_free((int*)bits[i]);
}
}
- free(bits);
- bits=NULL;
+ free(bits);
+ bits=NULL;
}
}
return bits;
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -155,7 +155,7 @@
}
/** Computes a cache of the pulses->bits mapping in each band */
-celt_int16 **compute_alloc_cache(CELTMode *m, int C, int M);
+celt_int16 **compute_alloc_cache(CELTMode *m, int M);
/** Compute the pulse allocation, i.e. how many pulses will go in each
* band.