Don't destroy stereo history when switching to mono.
The first version of the mono decoder with stereo output collapsed the historic energy values stored for anti-collapse down to one channel (by taking the max). This means that a subsequent switch back would continue on using the the maximum of the two values instead of the original history, which would make anti-collapse produce louder noise (and potentially more pre-echo than otherwise). This patch moves the max into the anti_collapse function itself, and does not store the values back into the source array, so the full stereo history is maintained if subsequent frames switch back. It also fixes an encoder mismatch, which never took the max (assuming, apparently, that the output channel count would never change).
This commit is contained in:
parent
948d27c9bc
commit
682b6cf1ad
3 changed files with 14 additions and 7 deletions
|
@ -212,7 +212,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm * restrict X, celt_sig
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This prevents energy collapse for transients with multiple short MDCTs */
|
/* This prevents energy collapse for transients with multiple short MDCTs */
|
||||||
void anti_collapse(const CELTMode *m, celt_norm *_X, unsigned char *collapse_masks, int LM, int C, int size,
|
void anti_collapse(const CELTMode *m, celt_norm *_X, unsigned char *collapse_masks, int LM, int C, int CC, int size,
|
||||||
int start, int end, celt_word16 *logE, celt_word16 *prev1logE,
|
int start, int end, celt_word16 *logE, celt_word16 *prev1logE,
|
||||||
celt_word16 *prev2logE, int *pulses, celt_uint32 seed)
|
celt_word16 *prev2logE, int *pulses, celt_uint32 seed)
|
||||||
{
|
{
|
||||||
|
@ -247,9 +247,18 @@ void anti_collapse(const CELTMode *m, celt_norm *_X, unsigned char *collapse_mas
|
||||||
c=0; do
|
c=0; do
|
||||||
{
|
{
|
||||||
celt_norm *X;
|
celt_norm *X;
|
||||||
|
celt_word16 prev1;
|
||||||
|
celt_word16 prev2;
|
||||||
celt_word16 Ediff;
|
celt_word16 Ediff;
|
||||||
celt_word16 r;
|
celt_word16 r;
|
||||||
Ediff = logE[c*m->nbEBands+i]-MIN16(prev1logE[c*m->nbEBands+i],prev2logE[c*m->nbEBands+i]);
|
prev1 = prev1logE[c*m->nbEBands+i];
|
||||||
|
prev2 = prev2logE[c*m->nbEBands+i];
|
||||||
|
if (C<CC)
|
||||||
|
{
|
||||||
|
prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]);
|
||||||
|
prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]);
|
||||||
|
}
|
||||||
|
Ediff = logE[c*m->nbEBands+i]-MIN16(prev1,prev2);
|
||||||
Ediff = MAX16(0, Ediff);
|
Ediff = MAX16(0, Ediff);
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
|
|
|
@ -93,7 +93,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||||
|
|
||||||
void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
|
void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
|
||||||
|
|
||||||
void anti_collapse(const CELTMode *m, celt_norm *_X, unsigned char *collapse_masks, int LM, int C, int size,
|
void anti_collapse(const CELTMode *m, celt_norm *_X, unsigned char *collapse_masks, int LM, int C, int CC, int size,
|
||||||
int start, int end, celt_word16 *logE, celt_word16 *prev1logE,
|
int start, int end, celt_word16 *logE, celt_word16 *prev1logE,
|
||||||
celt_word16 *prev2logE, int *pulses, celt_uint32 seed);
|
celt_word16 *prev2logE, int *pulses, celt_uint32 seed);
|
||||||
|
|
||||||
|
|
|
@ -1454,7 +1454,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
#endif
|
#endif
|
||||||
if (anti_collapse_on)
|
if (anti_collapse_on)
|
||||||
{
|
{
|
||||||
anti_collapse(st->mode, X, collapse_masks, LM, C, N,
|
anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
|
||||||
st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
|
st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2204,8 +2204,6 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
for (i=0;i<st->mode->nbEBands;i++)
|
for (i=0;i<st->mode->nbEBands;i++)
|
||||||
{
|
{
|
||||||
oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
|
oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]);
|
||||||
oldLogE[i]=MAX16(oldLogE[i],oldLogE[st->mode->nbEBands+i]);
|
|
||||||
oldLogE2[i]=MAX16(oldLogE2[i],oldLogE2[st->mode->nbEBands+i]);
|
|
||||||
backgroundLogE[i]=MAX16(backgroundLogE[i],backgroundLogE[st->mode->nbEBands+i]);
|
backgroundLogE[i]=MAX16(backgroundLogE[i],backgroundLogE[st->mode->nbEBands+i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2341,7 +2339,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
|
fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
|
||||||
|
|
||||||
if (anti_collapse_on)
|
if (anti_collapse_on)
|
||||||
anti_collapse(st->mode, X, collapse_masks, LM, C, N,
|
anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
|
||||||
st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
|
st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
|
||||||
|
|
||||||
log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
|
log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue