Some work towards being able to encode a 48 kHz stream from 32 kHz audio (incomplete)

This commit is contained in:
Jean-Marc Valin 2010-07-16 18:12:45 -04:00
parent 3b0df0dc2a
commit 85f41b20df
3 changed files with 40 additions and 17 deletions

View file

@ -725,6 +725,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
celt_int32 vbr_rate=0; celt_int32 vbr_rate=0;
celt_word16 max_decay; celt_word16 max_decay;
int nbFilledBytes, nbAvailableBytes; int nbFilledBytes, nbAvailableBytes;
int effEnd;
SAVE_STACK; SAVE_STACK;
if (check_encoder(st) != CELT_OK) if (check_encoder(st) != CELT_OK)
@ -754,6 +755,10 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
} }
nbAvailableBytes = nbCompressedBytes - nbFilledBytes; nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
effEnd = st->end;
if (effEnd > st->mode->effEBands)
effEnd = st->mode->effEBands;
N = M*st->mode->shortMdctSize; N = M*st->mode->shortMdctSize;
N4 = (N-st->overlap)>>1; N4 = (N-st->overlap)>>1;
ALLOC(in, 2*C*N-2*C*N4, celt_sig); ALLOC(in, 2*C*N-2*C*N4, celt_sig);
@ -858,23 +863,28 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
if (has_pitch) if (has_pitch)
apply_pitch(st->mode, freq, pitch_freq, gain_id, 1, C, M); apply_pitch(st->mode, freq, pitch_freq, gain_id, 1, C, M);
compute_band_energies(st->mode, freq, bandE, st->end, C, M); compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
for (i=0;i<st->end*C;i++) for (c=0;c<C;c++)
bandLogE[i] = amp2Log(bandE[i]); {
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 */ /* Band normalisation */
normalise_bands(st->mode, freq, X, bandE, 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, st->end, C, M)) if (!shortBlocks && !folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M))
has_fold = 0; has_fold = 0;
/* Don't use intra energy when we're operating at low bit-rate */ /* 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); 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; st->delayedIntra = 1;
else else
st->delayedIntra = 0; st->delayedIntra = 0;
NN = M*st->mode->eBands[st->end]; NN = M*st->mode->eBands[effEnd];
if (shortBlocks && !transient_shift) if (shortBlocks && !transient_shift)
{ {
celt_word32 sum[8]={1,1,1,1,1,1,1,1}; celt_word32 sum[8]={1,1,1,1,1,1,1,1};
@ -918,7 +928,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
} while (m<M-1); } while (m<M-1);
#endif #endif
if (mdct_weight_shift) 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 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
} }
ALLOC(tf_res, st->mode->nbEBands, int); 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 */ /* Bit allocation */
ALLOC(error, C*st->mode->nbEBands, celt_word16); ALLOC(error, C*st->mode->nbEBands, celt_word16);
@ -1047,7 +1059,8 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
quant_fine_energy(st->mode, st->start, st->end, 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 */ /* 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); 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 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
if (mdct_weight_shift) 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 */ /* 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)); CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
@ -1683,6 +1696,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
int gain_id=0; int gain_id=0;
int LM, M; int LM, M;
int nbFilledBytes, nbAvailableBytes; int nbFilledBytes, nbAvailableBytes;
int effEnd;
SAVE_STACK; SAVE_STACK;
if (check_decoder(st) != CELT_OK) if (check_decoder(st) != CELT_OK)
@ -1704,6 +1718,10 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
N = M*st->mode->shortMdctSize; N = M*st->mode->shortMdctSize;
N4 = (N-st->overlap)>>1; 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(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
ALLOC(bandE, st->mode->nbEBands*C, celt_ener); ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
@ -1711,7 +1729,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
for (i=0;i<M*st->mode->eBands[st->start];i++) for (i=0;i<M*st->mode->eBands[st->start];i++)
X[c*N+i] = 0; X[c*N+i] = 0;
for (c=0;c<C;c++) 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; X[c*N+i] = 0;
if (data == NULL) if (data == NULL)
@ -1809,17 +1827,18 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
} }
/* Decode fixed codebook and merge with pitch */ /* 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); 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) 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 */ /* 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)); CELT_MOVE(st->decode_mem, st->decode_mem+C*N, C*(DECODE_BUFFER_SIZE+st->overlap-N));
@ -1831,7 +1850,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
for (i=0;i<M*st->mode->eBands[st->start];i++) for (i=0;i<M*st->mode->eBands[st->start];i++)
freq[c*N+i] = 0; freq[c*N+i] = 0;
for (c=0;c<C;c++) 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; freq[c*N+i] = 0;
/* Compute inverse MDCTs */ /* Compute inverse MDCTs */

View file

@ -389,6 +389,9 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
if (mode->eBands==NULL) if (mode->eBands==NULL)
goto failure; goto failure;
mode->effEBands = mode->nbEBands;
while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
mode->effEBands--;
mode->pitchEnd = 4000*(celt_int32)mode->shortMdctSize/Fs; mode->pitchEnd = 4000*(celt_int32)mode->shortMdctSize/Fs;
/* Overlap must be divisible by 4 */ /* Overlap must be divisible by 4 */

View file

@ -85,6 +85,7 @@ struct CELTMode {
int overlap; int overlap;
int nbEBands; int nbEBands;
int effEBands;
int pitchEnd; int pitchEnd;
celt_word16 preemph[4]; celt_word16 preemph[4];
const celt_int16 *eBands; /**< Definition for each "pseudo-critical band" */ const celt_int16 *eBands; /**< Definition for each "pseudo-critical band" */