Making it possible for the stereo decoder to decode a mono stream
This commit is contained in:
parent
89039a3ff9
commit
f1916a14fd
2 changed files with 62 additions and 23 deletions
|
@ -1734,6 +1734,7 @@ struct CELTDecoder {
|
||||||
const CELTMode *mode;
|
const CELTMode *mode;
|
||||||
int overlap;
|
int overlap;
|
||||||
int channels;
|
int channels;
|
||||||
|
int stream_channels;
|
||||||
|
|
||||||
int downsample;
|
int downsample;
|
||||||
int start, end;
|
int start, end;
|
||||||
|
@ -1832,7 +1833,7 @@ CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int
|
||||||
|
|
||||||
st->mode = mode;
|
st->mode = mode;
|
||||||
st->overlap = mode->overlap;
|
st->overlap = mode->overlap;
|
||||||
st->channels = channels;
|
st->stream_channels = st->channels = channels;
|
||||||
|
|
||||||
st->downsample = 1;
|
st->downsample = 1;
|
||||||
st->start = 0;
|
st->start = 0;
|
||||||
|
@ -2102,7 +2103,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
int shortBlocks;
|
int shortBlocks;
|
||||||
int isTransient;
|
int isTransient;
|
||||||
int intra_ener;
|
int intra_ener;
|
||||||
const int C = CHANNELS(st->channels);
|
const int CC = CHANNELS(st->channels);
|
||||||
int LM, M;
|
int LM, M;
|
||||||
int effEnd;
|
int effEnd;
|
||||||
int codedBands;
|
int codedBands;
|
||||||
|
@ -2118,6 +2119,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
int anti_collapse_rsv;
|
int anti_collapse_rsv;
|
||||||
int anti_collapse_on=0;
|
int anti_collapse_on=0;
|
||||||
int silence;
|
int silence;
|
||||||
|
const int C = CHANNELS(st->stream_channels);
|
||||||
|
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
|
|
||||||
|
@ -2136,12 +2138,12 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
|
decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
|
||||||
out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
|
out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
|
||||||
overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
|
overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
|
||||||
} while (++c<C);
|
} while (++c<CC);
|
||||||
lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
|
lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC);
|
||||||
oldBandE = lpc+C*LPC_ORDER;
|
oldBandE = lpc+CC*LPC_ORDER;
|
||||||
oldLogE = oldBandE + C*st->mode->nbEBands;
|
oldLogE = oldBandE + CC*st->mode->nbEBands;
|
||||||
oldLogE2 = oldLogE + C*st->mode->nbEBands;
|
oldLogE2 = oldLogE + CC*st->mode->nbEBands;
|
||||||
backgroundLogE = oldLogE2 + C*st->mode->nbEBands;
|
backgroundLogE = oldLogE2 + CC*st->mode->nbEBands;
|
||||||
|
|
||||||
N = M*st->mode->shortMdctSize;
|
N = M*st->mode->shortMdctSize;
|
||||||
|
|
||||||
|
@ -2149,17 +2151,17 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
if (effEnd > st->mode->effEBands)
|
if (effEnd > st->mode->effEBands)
|
||||||
effEnd = st->mode->effEBands;
|
effEnd = st->mode->effEBands;
|
||||||
|
|
||||||
ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
|
ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
|
||||||
ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
|
ALLOC(X, CC*N, celt_norm); /**< Interleaved normalised MDCTs */
|
||||||
ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
|
ALLOC(bandE, st->mode->nbEBands*CC, celt_ener);
|
||||||
c=0; do
|
c=0; do
|
||||||
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;
|
||||||
while (++c<C);
|
while (++c<CC);
|
||||||
c=0; do
|
c=0; do
|
||||||
for (i=M*st->mode->eBands[effEnd];i<N;i++)
|
for (i=M*st->mode->eBands[effEnd];i<N;i++)
|
||||||
X[c*N+i] = 0;
|
X[c*N+i] = 0;
|
||||||
while (++c<C);
|
while (++c<CC);
|
||||||
|
|
||||||
if (data == NULL || len<=1)
|
if (data == NULL || len<=1)
|
||||||
{
|
{
|
||||||
|
@ -2179,6 +2181,21 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
dec = &_dec;
|
dec = &_dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CC==1&&C==2)
|
||||||
|
{
|
||||||
|
RESTORE_STACK;
|
||||||
|
return CELT_CORRUPTED_DATA;
|
||||||
|
} else if (CC==2&&C==1)
|
||||||
|
{
|
||||||
|
for (i=0;i<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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
total_bits = len*8;
|
total_bits = len*8;
|
||||||
tell = ec_dec_tell(dec, 0);
|
tell = ec_dec_tell(dec, 0);
|
||||||
|
|
||||||
|
@ -2327,7 +2344,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
|
denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
|
||||||
|
|
||||||
CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
|
CELT_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N);
|
||||||
if (C==2)
|
if (CC==2)
|
||||||
CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
|
CELT_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N);
|
||||||
|
|
||||||
c=0; do
|
c=0; do
|
||||||
|
@ -2343,11 +2360,17 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
} while (++c<C);
|
} while (++c<C);
|
||||||
|
|
||||||
out_syn[0] = out_mem[0]+MAX_PERIOD-N;
|
out_syn[0] = out_mem[0]+MAX_PERIOD-N;
|
||||||
if (C==2)
|
if (CC==2)
|
||||||
out_syn[1] = out_mem[1]+MAX_PERIOD-N;
|
out_syn[1] = out_mem[1]+MAX_PERIOD-N;
|
||||||
|
|
||||||
|
if (CC==2&&C==1)
|
||||||
|
{
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
freq[N+i] = freq[i];
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute inverse MDCTs */
|
/* Compute inverse MDCTs */
|
||||||
compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, C, LM);
|
compute_inv_mdcts(st->mode, shortBlocks, freq, out_syn, overlap_mem, CC, LM);
|
||||||
|
|
||||||
#ifdef ENABLE_POSTFILTER
|
#ifdef ENABLE_POSTFILTER
|
||||||
c=0; do {
|
c=0; do {
|
||||||
|
@ -2366,7 +2389,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
|
st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
|
||||||
st->mode->window, st->mode->overlap);
|
st->mode->window, st->mode->overlap);
|
||||||
}
|
}
|
||||||
} while (++c<C);
|
} while (++c<CC);
|
||||||
st->postfilter_period_old = st->postfilter_period;
|
st->postfilter_period_old = st->postfilter_period;
|
||||||
st->postfilter_gain_old = st->postfilter_gain;
|
st->postfilter_gain_old = st->postfilter_gain;
|
||||||
st->postfilter_tapset_old = st->postfilter_tapset;
|
st->postfilter_tapset_old = st->postfilter_tapset;
|
||||||
|
@ -2375,6 +2398,11 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
st->postfilter_tapset = postfilter_tapset;
|
st->postfilter_tapset = postfilter_tapset;
|
||||||
#endif /* ENABLE_POSTFILTER */
|
#endif /* ENABLE_POSTFILTER */
|
||||||
|
|
||||||
|
if (CC==2&&C==1) {
|
||||||
|
for (i=0;i<st->mode->nbEBands;i++)
|
||||||
|
oldBandE[st->mode->nbEBands+i]=oldBandE[i];
|
||||||
|
}
|
||||||
|
|
||||||
/* In case start or end were to change */
|
/* In case start or end were to change */
|
||||||
c=0; do
|
c=0; do
|
||||||
{
|
{
|
||||||
|
@ -2382,22 +2410,22 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
||||||
oldBandE[c*st->mode->nbEBands+i]=0;
|
oldBandE[c*st->mode->nbEBands+i]=0;
|
||||||
for (i=st->end;i<st->mode->nbEBands;i++)
|
for (i=st->end;i<st->mode->nbEBands;i++)
|
||||||
oldBandE[c*st->mode->nbEBands+i]=0;
|
oldBandE[c*st->mode->nbEBands+i]=0;
|
||||||
} while (++c<C);
|
} while (++c<CC);
|
||||||
if (!isTransient)
|
if (!isTransient)
|
||||||
{
|
{
|
||||||
for (i=0;i<C*st->mode->nbEBands;i++)
|
for (i=0;i<CC*st->mode->nbEBands;i++)
|
||||||
oldLogE2[i] = oldLogE[i];
|
oldLogE2[i] = oldLogE[i];
|
||||||
for (i=0;i<C*st->mode->nbEBands;i++)
|
for (i=0;i<CC*st->mode->nbEBands;i++)
|
||||||
oldLogE[i] = oldBandE[i];
|
oldLogE[i] = oldBandE[i];
|
||||||
for (i=0;i<C*st->mode->nbEBands;i++)
|
for (i=0;i<CC*st->mode->nbEBands;i++)
|
||||||
backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
|
backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]);
|
||||||
} else {
|
} else {
|
||||||
for (i=0;i<C*st->mode->nbEBands;i++)
|
for (i=0;i<CC*st->mode->nbEBands;i++)
|
||||||
oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
|
oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
|
||||||
}
|
}
|
||||||
st->rng = dec->rng;
|
st->rng = dec->rng;
|
||||||
|
|
||||||
deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
|
deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
|
||||||
st->loss_count = 0;
|
st->loss_count = 0;
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
if (ec_dec_tell(dec,0) > 8*len || ec_dec_get_error(dec))
|
if (ec_dec_tell(dec,0) > 8*len || ec_dec_get_error(dec))
|
||||||
|
@ -2512,6 +2540,14 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
|
||||||
st->end = value;
|
st->end = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CELT_SET_CHANNELS_REQUEST:
|
||||||
|
{
|
||||||
|
celt_int32 value = va_arg(ap, celt_int32);
|
||||||
|
if (value<1 || value>2)
|
||||||
|
goto bad_arg;
|
||||||
|
st->stream_channels = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CELT_RESET_STATE:
|
case CELT_RESET_STATE:
|
||||||
{
|
{
|
||||||
CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
|
CELT_MEMSET((char*)&st->DECODER_RESET_START, 0,
|
||||||
|
|
|
@ -104,6 +104,9 @@ extern "C" {
|
||||||
#define CELT_SET_END_BAND_REQUEST 10001
|
#define CELT_SET_END_BAND_REQUEST 10001
|
||||||
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
|
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
|
||||||
|
|
||||||
|
#define CELT_SET_CHANNELS_REQUEST 10002
|
||||||
|
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, _celt_check_int(x)
|
||||||
|
|
||||||
/** GET the lookahead used in the current mode */
|
/** GET the lookahead used in the current mode */
|
||||||
#define CELT_GET_LOOKAHEAD 1001
|
#define CELT_GET_LOOKAHEAD 1001
|
||||||
/** GET the sample rate used in the current mode */
|
/** GET the sample rate used in the current mode */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue