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.
This commit is contained in:
parent
4aa1b8df26
commit
cae30df09a
7 changed files with 66 additions and 65 deletions
|
@ -316,9 +316,7 @@ void apply_pitch(const CELTMode *m, celt_sig *X, const celt_sig *P, int gain_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#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 N)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int i = bandID;
|
int i = bandID;
|
||||||
const celt_int16 *eBands = m->eBands;
|
const celt_int16 *eBands = m->eBands;
|
||||||
|
@ -341,7 +339,7 @@ static void stereo_band_mix(const CELTMode *m, celt_norm *X, celt_norm *Y, const
|
||||||
a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
|
a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
|
||||||
a2 = dir*DIV32_16(SHL32(EXTEND32(right),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;
|
celt_norm r, l;
|
||||||
l = X[j];
|
l = X[j];
|
||||||
|
@ -352,8 +350,6 @@ static void stereo_band_mix(const CELTMode *m, celt_norm *X, celt_norm *Y, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* DISABLE_STEREO */
|
|
||||||
|
|
||||||
int folding_decision(const CELTMode *m, celt_norm *X, celt_word16 *average, int *last_decision, int _C, int M)
|
int folding_decision(const CELTMode *m, celt_norm *X, celt_word16 *average, int *last_decision, int _C, int M)
|
||||||
{
|
{
|
||||||
int i, c, N0;
|
int i, c, N0;
|
||||||
|
@ -439,13 +435,16 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
|
||||||
split = stereo = Y != NULL;
|
split = stereo = Y != NULL;
|
||||||
|
|
||||||
/* If we need more than 32 bits, try splitting the band in two. */
|
/* 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))))
|
||||||
|
{
|
||||||
|
if (LM>0 || (N&1)==0)
|
||||||
{
|
{
|
||||||
N >>= 1;
|
N >>= 1;
|
||||||
Y = X+N;
|
Y = X+N;
|
||||||
split = 1;
|
split = 1;
|
||||||
LM -= 1;
|
LM -= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (split)
|
if (split)
|
||||||
{
|
{
|
||||||
|
@ -468,7 +467,7 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
|
||||||
if (encode)
|
if (encode)
|
||||||
{
|
{
|
||||||
if (stereo)
|
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);
|
mid = renormalise_vector(X, Q15ONE, N, 1);
|
||||||
side = renormalise_vector(Y, Q15ONE, N, 1);
|
side = renormalise_vector(Y, Q15ONE, N, 1);
|
||||||
|
@ -644,10 +643,12 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* This is the basis no-split case */
|
/* This is the basic no-split case */
|
||||||
q = bits2pulses(m, m->bits[LM][i], N, b);
|
q = bits2pulses(m, m->bits[LM][i], N, b);
|
||||||
curr_bits = pulses2bits(m->bits[LM][i], N, q);
|
curr_bits = pulses2bits(m->bits[LM][i], N, q);
|
||||||
*remaining_bits -= curr_bits;
|
*remaining_bits -= curr_bits;
|
||||||
|
|
||||||
|
/* Ensures we can never bust the budget */
|
||||||
while (*remaining_bits < 0 && q > 0)
|
while (*remaining_bits < 0 && q > 0)
|
||||||
{
|
{
|
||||||
*remaining_bits += curr_bits;
|
*remaining_bits += curr_bits;
|
||||||
|
@ -655,6 +656,11 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
|
||||||
curr_bits = pulses2bits(m->bits[LM][i], N, q);
|
curr_bits = pulses2bits(m->bits[LM][i], N, q);
|
||||||
*remaining_bits -= curr_bits;
|
*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)
|
if (encode)
|
||||||
alg_quant(X, N, q, spread, lowband, resynth, ec);
|
alg_quant(X, N, q, spread, lowband, resynth, ec);
|
||||||
else
|
else
|
||||||
|
@ -746,7 +752,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm *_X, ce
|
||||||
|
|
||||||
if (resynth && _Y != NULL)
|
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(X, Q15ONE, N, 1);
|
||||||
renormalise_vector(Y, Q15ONE, N, 1);
|
renormalise_vector(Y, Q15ONE, N, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,15 +141,6 @@ CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error)
|
||||||
*error = CELT_INVALID_MODE;
|
*error = CELT_INVALID_MODE;
|
||||||
return NULL;
|
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)
|
if (channels < 0 || channels > 2)
|
||||||
{
|
{
|
||||||
|
@ -1217,15 +1208,6 @@ CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
|
||||||
*error = CELT_INVALID_MODE;
|
*error = CELT_INVALID_MODE;
|
||||||
return NULL;
|
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)
|
if (channels < 0 || channels > 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -854,21 +854,10 @@ static inline void encode_pulses32(int _n,int _k,const int *_y,ec_enc *_enc){
|
||||||
|
|
||||||
void encode_pulses(int *_y, int N, int K, ec_enc *enc)
|
void encode_pulses(int *_y, int N, int K, ec_enc *enc)
|
||||||
{
|
{
|
||||||
if (K==0) {
|
if (K==0)
|
||||||
} else if(fits_in32(N,K))
|
return;
|
||||||
{
|
celt_assert(fits_in32(N,K));
|
||||||
encode_pulses32(N, K, _y, enc);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void decode_pulses32(int _n,int _k,int *_y,ec_dec *_dec){
|
static inline void decode_pulses32(int _n,int _k,int *_y,ec_dec *_dec){
|
||||||
|
@ -900,14 +889,9 @@ void decode_pulses(int *_y, int N, int K, ec_dec *dec)
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<N;i++)
|
for (i=0;i<N;i++)
|
||||||
_y[i] = 0;
|
_y[i] = 0;
|
||||||
} else if(fits_in32(N,K))
|
} else
|
||||||
{
|
{
|
||||||
|
celt_assert (fits_in32(N,K));
|
||||||
decode_pulses32(N, K, _y, dec);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,9 +380,15 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
|
||||||
#endif
|
#endif
|
||||||
mode->window = window;
|
mode->window = window;
|
||||||
|
|
||||||
|
mode->bits = mode->_bits+1;
|
||||||
for (i=0;(1<<i)<=mode->nbShortMdcts;i++)
|
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;
|
goto failure;
|
||||||
|
|
||||||
logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
|
logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
|
||||||
|
@ -459,6 +465,19 @@ void celt_mode_destroy(CELTMode *mode)
|
||||||
}
|
}
|
||||||
celt_free((celt_int16**)mode->bits[m]);
|
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->eBands);
|
||||||
celt_free((celt_int16*)mode->allocVectors);
|
celt_free((celt_int16*)mode->allocVectors);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "mdct.h"
|
#include "mdct.h"
|
||||||
#include "pitch.h"
|
#include "pitch.h"
|
||||||
|
|
||||||
#define MAX_CONFIG_SIZES 4
|
#define MAX_CONFIG_SIZES 5
|
||||||
|
|
||||||
#define CELT_BITSTREAM_VERSION 0x8000000c
|
#define CELT_BITSTREAM_VERSION 0x8000000c
|
||||||
|
|
||||||
|
@ -93,7 +93,8 @@ struct CELTMode {
|
||||||
int nbAllocVectors; /**< Number of lines in the matrix below */
|
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 *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 */
|
/* Stuff that could go in the {en,de}coder, but we save space this way */
|
||||||
mdct_lookup mdct[MAX_CONFIG_SIZES];
|
mdct_lookup mdct[MAX_CONFIG_SIZES];
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
|
|
||||||
#ifndef STATIC_MODES
|
#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 i, prevN;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
@ -60,8 +60,17 @@ celt_int16 **compute_alloc_cache(CELTMode *m, int C, int M)
|
||||||
prevN = -1;
|
prevN = -1;
|
||||||
for (i=0;i<m->nbEBands;i++)
|
for (i=0;i<m->nbEBands;i++)
|
||||||
{
|
{
|
||||||
int N = C*M*(eBands[i+1]-eBands[i]);
|
int N;
|
||||||
if (N == prevN && M*eBands[i] < m->pitchEnd)
|
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];
|
bits[i] = bits[i-1];
|
||||||
} else {
|
} else {
|
||||||
|
@ -85,7 +94,7 @@ celt_int16 **compute_alloc_cache(CELTMode *m, int C, int M)
|
||||||
{
|
{
|
||||||
for (i=0;i<m->nbEBands;i++)
|
for (i=0;i<m->nbEBands;i++)
|
||||||
{
|
{
|
||||||
if (bits[i] != prevPtr)
|
if (bits[i] != prevPtr && bits[i] != NULL)
|
||||||
{
|
{
|
||||||
prevPtr = bits[i];
|
prevPtr = bits[i];
|
||||||
celt_free((int*)bits[i]);
|
celt_free((int*)bits[i]);
|
||||||
|
|
|
@ -155,7 +155,7 @@ static inline int pulses2bits(const celt_int16 *cache, int N, int pulses)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Computes a cache of the pulses->bits mapping in each band */
|
/** 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
|
/** Compute the pulse allocation, i.e. how many pulses will go in each
|
||||||
* band.
|
* band.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue