ref: 85f41b20df8559dc85780201603352eb66489df5
parent: 3b0df0dc2a0f17bdff7b41d2b437e3e042fec1bc
author: Jean-Marc Valin <[email protected]>
date: Fri Jul 16 14:12:45 EDT 2010
Some work towards being able to encode a 48 kHz stream from 32 kHz audio (incomplete)
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -725,6 +725,7 @@
celt_int32 vbr_rate=0;
celt_word16 max_decay;
int nbFilledBytes, nbAvailableBytes;
+ int effEnd;
SAVE_STACK;
if (check_encoder(st) != CELT_OK)
@@ -754,6 +755,10 @@
}
nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
+ effEnd = st->end;
+ if (effEnd > st->mode->effEBands)
+ effEnd = st->mode->effEBands;
+
N = M*st->mode->shortMdctSize;
N4 = (N-st->overlap)>>1;
ALLOC(in, 2*C*N-2*C*N4, celt_sig);
@@ -858,23 +863,28 @@
if (has_pitch)
apply_pitch(st->mode, freq, pitch_freq, gain_id, 1, C, M);
- compute_band_energies(st->mode, freq, bandE, st->end, C, M);
- for (i=0;i<st->end*C;i++)
- bandLogE[i] = amp2Log(bandE[i]);
+ compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
+ for (c=0;c<C;c++)
+ {
+ for (i=0;i<effEnd;i++)
+ bandLogE[c*st->mode->nbEBands+i] = amp2Log(bandE[c*st->mode->nbEBands+i]);
+ for (i=effEnd;i<st->end;i++)
+ bandLogE[c*st->mode->nbEBands+i] = -QCONST16(7.f,DB_SHIFT);
+ }
/* Band normalisation */
- normalise_bands(st->mode, freq, X, bandE, st->end, C, M);
- if (!shortBlocks && !folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, st->end, C, M))
+ normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
+ if (!shortBlocks && !folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M))
has_fold = 0;
/* Don't use intra energy when we're operating at low bit-rate */
intra_ener = st->force_intra || (!has_pitch && st->delayedIntra && nbAvailableBytes > st->end);
- if (shortBlocks || intra_decision(bandLogE, st->oldBandE, st->end))
+ if (shortBlocks || intra_decision(bandLogE, st->oldBandE, effEnd))
st->delayedIntra = 1;
else
st->delayedIntra = 0;
- NN = M*st->mode->eBands[st->end];
+ NN = M*st->mode->eBands[effEnd];
if (shortBlocks && !transient_shift)
{
celt_word32 sum[8]={1,1,1,1,1,1,1,1};
@@ -918,7 +928,7 @@
} while (m<M-1);
#endif
if (mdct_weight_shift)
- mdct_shape(st->mode, X, mdct_weight_pos+1, M, N, mdct_weight_shift, st->end, C, 0, M);
+ mdct_shape(st->mode, X, mdct_weight_pos+1, M, N, mdct_weight_shift, effEnd, C, 0, M);
}
@@ -960,7 +970,9 @@
}
ALLOC(tf_res, st->mode->nbEBands, int);
- tf_select = tf_analysis(bandLogE, st->oldBandE, st->end, C, isTransient, tf_res, nbAvailableBytes);
+ tf_select = tf_analysis(bandLogE, st->oldBandE, effEnd, C, isTransient, tf_res, nbAvailableBytes);
+ for (i=effEnd;i<st->end;i++)
+ tf_res[i] = tf_res[effEnd-1];
/* Bit allocation */
ALLOC(error, C*st->mode->nbEBands, celt_word16);
@@ -1047,7 +1059,8 @@
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, st->end, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
+ /* FIXME: we can't just stop at effEnd because we'll have an allocation mismatch */
+ quant_all_bands(1, st->mode, st->start, effEnd, 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, st->end, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
@@ -1059,11 +1072,11 @@
if (mdct_weight_shift)
{
- mdct_shape(st->mode, X, 0, mdct_weight_pos+1, N, mdct_weight_shift, st->end, C, 1, M);
+ mdct_shape(st->mode, X, 0, mdct_weight_pos+1, N, mdct_weight_shift, effEnd, C, 1, M);
}
/* Synthesis */
- denormalise_bands(st->mode, X, freq, bandE, st->end, C, M);
+ denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
@@ -1683,6 +1696,7 @@
int gain_id=0;
int LM, M;
int nbFilledBytes, nbAvailableBytes;
+ int effEnd;
SAVE_STACK;
if (check_decoder(st) != CELT_OK)
@@ -1704,6 +1718,10 @@
N = M*st->mode->shortMdctSize;
N4 = (N-st->overlap)>>1;
+ effEnd = st->end;
+ if (effEnd > st->mode->effEBands)
+ effEnd = st->mode->effEBands;
+
ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
@@ -1711,7 +1729,7 @@
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++)
+ for (i=M*st->mode->eBands[effEnd];i<N;i++)
X[c*N+i] = 0;
if (data == NULL)
@@ -1809,17 +1827,18 @@
}
/* Decode fixed codebook and merge with pitch */
- 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);
+ /* FIXME: we can't just stop at effEnd because we'll have an allocation mismatch */
+ quant_all_bands(0, st->mode, st->start, effEnd, 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, st->end, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
if (mdct_weight_shift)
{
- mdct_shape(st->mode, X, 0, mdct_weight_pos+1, N, mdct_weight_shift, st->end, C, 1, M);
+ mdct_shape(st->mode, X, 0, mdct_weight_pos+1, N, mdct_weight_shift, effEnd, C, 1, M);
}
/* Synthesis */
- denormalise_bands(st->mode, X, freq, bandE, st->end, C, M);
+ denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
CELT_MOVE(st->decode_mem, st->decode_mem+C*N, C*(DECODE_BUFFER_SIZE+st->overlap-N));
@@ -1831,7 +1850,7 @@
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++)
+ for (i=M*st->mode->eBands[effEnd];i<N;i++)
freq[c*N+i] = 0;
/* Compute inverse MDCTs */
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -389,6 +389,9 @@
if (mode->eBands==NULL)
goto failure;
+ mode->effEBands = mode->nbEBands;
+ while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
+ mode->effEBands--;
mode->pitchEnd = 4000*(celt_int32)mode->shortMdctSize/Fs;
/* Overlap must be divisible by 4 */
--- a/libcelt/modes.h
+++ b/libcelt/modes.h
@@ -85,6 +85,7 @@
int overlap;
int nbEBands;
+ int effEBands;
int pitchEnd;
celt_word16 preemph[4];
const celt_int16 *eBands; /**< Definition for each "pseudo-critical band" */