Commit 525d7cfd authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Support for adjusting the end band

parent 41a5593c
......@@ -884,7 +884,7 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
}
}
void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm *_X, celt_norm *_Y, const celt_ener *bandE, int *pulses, int shortBlocks, int fold, int *tf_res, int resynth, int total_bits, void *ec, int LM)
void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm *_X, celt_norm *_Y, const celt_ener *bandE, int *pulses, int shortBlocks, int fold, int *tf_res, int resynth, int total_bits, void *ec, int LM)
{
int i, balance;
celt_int32 remaining_bits;
......@@ -907,7 +907,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm *_X, ce
balance = 0;
lowband = NULL;
for (i=start;i<m->nbEBands;i++)
for (i=start;i<end;i++)
{
int tell;
int b;
......@@ -930,7 +930,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm *_X, ce
if (i != start)
balance -= tell;
remaining_bits = (total_bits<<BITRES)-tell-1;
curr_balance = (m->nbEBands-i);
curr_balance = (end-i);
if (curr_balance > 3)
curr_balance = 3;
curr_balance = balance / curr_balance;
......
......@@ -85,7 +85,7 @@ int folding_decision(const CELTMode *m, celt_norm *X, celt_word16 *average, int
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param enc Entropy encoder
*/
void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm * X, celt_norm * Y, const celt_ener *bandE, int *pulses, int time_domain, int fold, int *tf_res, int resynth, int total_bits, void *enc, int M);
void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm * X, celt_norm * Y, const celt_ener *bandE, int *pulses, int time_domain, int fold, int *tf_res, int resynth, int total_bits, void *enc, int M);
void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
......
......@@ -963,7 +963,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
#else
max_decay = .125*nbAvailableBytes;
#endif
coarse_needed = quant_coarse_energy(st->mode, st->start, bandLogE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C, max_decay);
coarse_needed = quant_coarse_energy(st->mode, st->start, st->end, bandLogE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C, max_decay);
coarse_needed -= nbFilledBytes*8;
coarse_needed = ((coarse_needed*3-1)>>3)+1;
if (coarse_needed > nbAvailableBytes)
......@@ -1035,14 +1035,14 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
for (i=0;i<st->mode->nbEBands;i++)
offsets[i] = 0;
bits = nbCompressedBytes*8 - ec_enc_tell(enc, 0) - 1;
compute_allocation(st->mode, st->start, offsets, bits, pulses, fine_quant, fine_priority, C, M);
compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
quant_fine_energy(st->mode, st->start, bandE, st->oldBandE, error, fine_quant, enc, C);
quant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, enc, C);
/* Residual quantisation */
quant_all_bands(1, st->mode, st->start, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
quant_energy_finalise(st->mode, st->start, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
quant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
/* Re-synthesis of the coded audio if required */
if (resynth)
......@@ -1236,6 +1236,14 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
st->start = value;
}
break;
case CELT_SET_END_BAND_REQUEST:
{
celt_int32 value = va_arg(ap, celt_int32);
if (value<0 || value>=st->mode->nbEBands)
goto bad_arg;
st->end = value;
}
break;
case CELT_SET_PREDICTION_REQUEST:
{
int value = va_arg(ap, celt_int32);
......@@ -1686,6 +1694,9 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
for (c=0;c<C;c++)
for (i=0;i<M*st->mode->eBands[st->start];i++)
X[c*N+i] = 0;
for (c=0;c<C;c++)
for (i=M*st->mode->eBands[st->end];i<N;i++)
X[c*N+i] = 0;
if (data == NULL)
{
......@@ -1752,7 +1763,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
ALLOC(fine_quant, st->mode->nbEBands, int);
/* Get band energies */
unquant_coarse_energy(st->mode, st->start, bandE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, dec, C);
unquant_coarse_energy(st->mode, st->start, st->end, bandE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, dec, C);
ALLOC(tf_res, st->mode->nbEBands, int);
tf_decode(st->mode->nbEBands, C, isTransient, tf_res, nbAvailableBytes, LM, dec);
......@@ -1765,11 +1776,11 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
offsets[i] = 0;
bits = len*8 - ec_dec_tell(dec, 0) - 1;
compute_allocation(st->mode, st->start, offsets, bits, pulses, fine_quant, fine_priority, C, M);
compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
/*bits = ec_dec_tell(dec, 0);
compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(dec, 0)-bits))/C);*/
unquant_fine_energy(st->mode, st->start, bandE, st->oldBandE, fine_quant, dec, C);
unquant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, dec, C);
ALLOC(pitch_freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
if (has_pitch)
......@@ -1779,9 +1790,9 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
}
/* Decode fixed codebook and merge with pitch */
quant_all_bands(0, st->mode, st->start, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
unquant_energy_finalise(st->mode, st->start, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
unquant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
if (mdct_weight_shift)
{
......@@ -1800,6 +1811,9 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
for (c=0;c<C;c++)
for (i=0;i<M*st->mode->eBands[st->start];i++)
freq[c*N+i] = 0;
for (c=0;c<C;c++)
for (i=M*st->mode->eBands[st->end];i<N;i++)
freq[c*N+i] = 0;
/* Compute inverse MDCTs */
compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem, C, LM);
......@@ -1923,6 +1937,14 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
st->start = value;
}
break;
case CELT_SET_END_BAND_REQUEST:
{
celt_int32 value = va_arg(ap, celt_int32);
if (value<0 || value>=st->mode->nbEBands)
goto bad_arg;
st->end = value;
}
break;
case CELT_RESET_STATE:
{
const CELTMode *mode = st->mode;
......
......@@ -96,9 +96,11 @@ extern "C" {
#define CELT_RESET_STATE CELT_RESET_STATE_REQUEST
#define CELT_SET_START_BAND_REQUEST 10000
/** Controls the complexity from 0-10 (int) */
#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, _celt_check_int(x)
#define CELT_SET_END_BAND_REQUEST 10001
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
/** GET the lookahead used in the current mode */
#define CELT_GET_LOOKAHEAD 1001
/** GET the sample rate used in the current mode */
......
......@@ -84,7 +84,7 @@ void quant_prob_free(int *freq)
celt_free(freq);
}
unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay)
unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay)
{
int i, c;
unsigned bits_used = 0;
......@@ -102,7 +102,7 @@ unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eB
beta = MULT16_16_P15(QCONST16(.8f,15),coef);
/* Encode at a fixed coarse resolution */
for (i=start;i<m->nbEBands;i++)
for (i=start;i<end;i++)
{
c=0;
do {
......@@ -147,13 +147,13 @@ unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eB
return bits_used;
}
void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
{
int i, c;
const int C = CHANNELS(_C);
/* Encode finer resolution */
for (i=start;i<m->nbEBands;i++)
for (i=start;i<end;i++)
{
celt_int16 frac = 1<<fine_quant[i];
if (fine_quant[i] <= 0)
......@@ -185,7 +185,7 @@ void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_wor
}
}
void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C)
void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C)
{
int i, prio, c;
const int C = CHANNELS(_C);
......@@ -193,7 +193,7 @@ void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt
/* Use up the remaining bits */
for (prio=0;prio<2;prio++)
{
for (i=start;i<m->nbEBands && bits_left>=C ;i++)
for (i=start;i<end && bits_left>=C ;i++)
{
if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
continue;
......@@ -224,7 +224,7 @@ void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt
} while (++c < C);
}
void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C)
void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C)
{
int i, c;
celt_word32 prev[2] = {0, 0};
......@@ -241,7 +241,7 @@ void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt
beta = MULT16_16_P15(QCONST16(.8f,15),coef);
/* Decode at a fixed coarse resolution */
for (i=start;i<m->nbEBands;i++)
for (i=start;i<end;i++)
{
c=0;
do {
......@@ -262,12 +262,12 @@ void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt
}
}
void unquant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C)
void unquant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C)
{
int i, c;
const int C = CHANNELS(_C);
/* Decode finer resolution */
for (i=start;i<m->nbEBands;i++)
for (i=start;i<end;i++)
{
if (fine_quant[i] <= 0)
continue;
......@@ -286,7 +286,7 @@ void unquant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_w
}
}
void unquant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int _C)
void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int _C)
{
int i, prio, c;
const int C = CHANNELS(_C);
......@@ -294,7 +294,7 @@ void unquant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, ce
/* Use up the remaining bits */
for (prio=0;prio<2;prio++)
{
for (i=start;i<m->nbEBands && bits_left>=C ;i++)
for (i=start;i<end && bits_left>=C ;i++)
{
if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
continue;
......
......@@ -56,16 +56,16 @@ void compute_fine_allocation(const CELTMode *m, int *bits, int budget);
int intra_decision(celt_word16 *eBands, celt_word16 *oldEBands, int len);
unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay);
unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay);
void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C);
void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C);
void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C);
void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C);
void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C);
void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C);
void unquant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C);
void unquant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C);
void unquant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int _C);
void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int _C);
#endif /* QUANT_BANDS */
......@@ -111,7 +111,7 @@ celt_int16 **compute_alloc_cache(CELTMode *m, int M)
static inline void interp_bits2pulses(const CELTMode *m, int start, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len, int _C, int M)
static inline void interp_bits2pulses(const CELTMode *m, int start, int end, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len, int _C, int M)
{
int psum;
int lo, hi;
......@@ -127,7 +127,7 @@ static inline void interp_bits2pulses(const CELTMode *m, int start, int *bits1,
{
int mid = (lo+hi)>>1;
psum = 0;
for (j=start;j<len;j++)
for (j=start;j<end;j++)
psum += (((1<<BITRES)-mid)*bits1[j] + mid*bits2[j])>>BITRES;
if (psum > (total<<BITRES))
hi = mid;
......@@ -136,7 +136,7 @@ static inline void interp_bits2pulses(const CELTMode *m, int start, int *bits1,
}
psum = 0;
/*printf ("interp bisection gave %d\n", lo);*/
for (j=start;j<len;j++)
for (j=start;j<end;j++)
{
bits[j] = (((1<<BITRES)-lo)*bits1[j] + lo*bits2[j])>>BITRES;
psum += bits[j];
......@@ -145,14 +145,14 @@ static inline void interp_bits2pulses(const CELTMode *m, int start, int *bits1,
{
int left, perband;
left = (total<<BITRES)-psum;
perband = left/(len-start);
for (j=start;j<len;j++)
perband = left/(end-start);
for (j=start;j<end;j++)
bits[j] += perband;
left = left-len*perband;
left = left-end*perband;
for (j=start;j<start+left;j++)
bits[j]++;
}
for (j=start;j<len;j++)
for (j=start;j<end;j++)
{
int N, d;
int offset;
......@@ -187,7 +187,7 @@ static inline void interp_bits2pulses(const CELTMode *m, int start, int *bits1,
RESTORE_STACK;
}
void compute_allocation(const CELTMode *m, int start, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M)
void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M)
{
int lo, hi, len, j;
const int C = CHANNELS(_C);
......@@ -205,7 +205,7 @@ void compute_allocation(const CELTMode *m, int start, int *offsets, int total, i
{
int psum = 0;
int mid = (lo+hi) >> 1;
for (j=start;j<len;j++)
for (j=start;j<end;j++)
{
int N = m->eBands[j+1]-m->eBands[j];
bits1[j] = (C*M*N*m->allocVectors[mid*len+j] + offsets[j]);
......@@ -222,7 +222,7 @@ void compute_allocation(const CELTMode *m, int start, int *offsets, int total, i
/*printf ("lo = %d, hi = %d\n", lo, hi);*/
}
/*printf ("interp between %d and %d\n", lo, hi);*/
for (j=start;j<len;j++)
for (j=start;j<end;j++)
{
int N = m->eBands[j+1]-m->eBands[j];
bits1[j] = C*M*N*m->allocVectors[lo*len+j] + offsets[j];
......@@ -232,7 +232,7 @@ void compute_allocation(const CELTMode *m, int start, int *offsets, int total, i
if (bits2[j] < 0)
bits2[j] = 0;
}
interp_bits2pulses(m, start, bits1, bits2, total, pulses, ebits, fine_priority, len, C, M);
interp_bits2pulses(m, start, end, bits1, bits2, total, pulses, ebits, fine_priority, len, C, M);
RESTORE_STACK;
}
......@@ -166,7 +166,7 @@ celt_int16 **compute_alloc_cache(CELTMode *m, int M);
@param pulses Number of pulses per band (returned)
@return Total number of bits allocated
*/
void compute_allocation(const CELTMode *m, int start, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M);
void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M);
#endif
......@@ -64,17 +64,4 @@ void alg_unquant(celt_norm *X, int N, int K, int spread, celt_norm *lowband, ec_
celt_word16 renormalise_vector(celt_norm *X, celt_word16 value, int N, int stride);
/** Intra-frame predictor that matches a section of the current frame (at lower
* frequencies) to encode the current band.
* @param x Residual signal to quantise/encode (returns quantised version)
* @param W Perceptual weight
* @param N Number of samples to encode
* @param K Number of pulses to use
* @param Y Lower frequency spectrum to use, normalised to the same standard deviation
* @param P Pitch vector (it is assumed that p+x is a unit vector)
* @param B Stride (number of channels multiplied by the number of MDCTs per frame)
* @param N0 Number of valid offsets
*/
void intra_fold(const CELTMode *m, int start, int N, const celt_norm * restrict Y, celt_norm * restrict P, int N0, int B, int M);
#endif /* VQ_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment