Making the stereo encoder capable of encoding in mono
This commit is contained in:
parent
f1916a14fd
commit
00a98f5deb
1 changed files with 54 additions and 28 deletions
|
@ -96,6 +96,7 @@ struct CELTEncoder {
|
||||||
const CELTMode *mode; /**< Mode used by the encoder */
|
const CELTMode *mode; /**< Mode used by the encoder */
|
||||||
int overlap;
|
int overlap;
|
||||||
int channels;
|
int channels;
|
||||||
|
int stream_channels;
|
||||||
|
|
||||||
int force_intra;
|
int force_intra;
|
||||||
int complexity;
|
int complexity;
|
||||||
|
@ -216,7 +217,7 @@ CELTEncoder *celt_encoder_init_custom(CELTEncoder *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->upsample = 1;
|
st->upsample = 1;
|
||||||
st->start = 0;
|
st->start = 0;
|
||||||
|
@ -870,7 +871,8 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
int shortBlocks=0;
|
int shortBlocks=0;
|
||||||
int isTransient=0;
|
int isTransient=0;
|
||||||
int resynth;
|
int resynth;
|
||||||
const int C = CHANNELS(st->channels);
|
const int CC = CHANNELS(st->channels);
|
||||||
|
const int C = CHANNELS(st->stream_channels);
|
||||||
int LM, M;
|
int LM, M;
|
||||||
int tf_select;
|
int tf_select;
|
||||||
int nbFilledBytes, nbAvailableBytes;
|
int nbFilledBytes, nbAvailableBytes;
|
||||||
|
@ -907,12 +909,12 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
return CELT_BAD_ARG;
|
return CELT_BAD_ARG;
|
||||||
M=1<<LM;
|
M=1<<LM;
|
||||||
|
|
||||||
prefilter_mem = st->in_mem+C*(st->overlap);
|
prefilter_mem = st->in_mem+CC*(st->overlap);
|
||||||
_overlap_mem = prefilter_mem+C*COMBFILTER_MAXPERIOD;
|
_overlap_mem = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
|
||||||
/*_overlap_mem = st->in_mem+C*(st->overlap);*/
|
/*_overlap_mem = st->in_mem+C*(st->overlap);*/
|
||||||
oldBandE = (celt_word16*)(st->in_mem+C*(2*st->overlap+COMBFILTER_MAXPERIOD));
|
oldBandE = (celt_word16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD));
|
||||||
oldLogE = oldBandE + C*st->mode->nbEBands;
|
oldLogE = oldBandE + CC*st->mode->nbEBands;
|
||||||
oldLogE2 = oldLogE + C*st->mode->nbEBands;
|
oldLogE2 = oldLogE + CC*st->mode->nbEBands;
|
||||||
|
|
||||||
if (enc==NULL)
|
if (enc==NULL)
|
||||||
{
|
{
|
||||||
|
@ -963,7 +965,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
effEnd = st->mode->effEBands;
|
effEnd = st->mode->effEBands;
|
||||||
|
|
||||||
N = M*st->mode->shortMdctSize;
|
N = M*st->mode->shortMdctSize;
|
||||||
ALLOC(in, C*(N+st->overlap), celt_sig);
|
ALLOC(in, CC*(N+st->overlap), celt_sig);
|
||||||
|
|
||||||
/* Find pitch period and gain */
|
/* Find pitch period and gain */
|
||||||
{
|
{
|
||||||
|
@ -971,7 +973,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
celt_sig *pre[2];
|
celt_sig *pre[2];
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
c = 0;
|
c = 0;
|
||||||
ALLOC(_pre, C*(N+COMBFILTER_MAXPERIOD), celt_sig);
|
ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
|
||||||
|
|
||||||
pre[0] = _pre;
|
pre[0] = _pre;
|
||||||
pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
|
pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
|
||||||
|
@ -990,7 +992,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
if (++count==st->upsample)
|
if (++count==st->upsample)
|
||||||
{
|
{
|
||||||
count=0;
|
count=0;
|
||||||
pcmp+=C;
|
pcmp+=CC;
|
||||||
} else {
|
} else {
|
||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1006,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
}
|
}
|
||||||
CELT_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
|
CELT_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
|
||||||
CELT_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
|
CELT_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N);
|
||||||
} while (++c<C);
|
} while (++c<CC);
|
||||||
|
|
||||||
if (tell==1)
|
if (tell==1)
|
||||||
ec_enc_bit_logp(enc, silence, 15);
|
ec_enc_bit_logp(enc, silence, 15);
|
||||||
|
@ -1031,7 +1033,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
VARDECL(celt_word16, pitch_buf);
|
VARDECL(celt_word16, pitch_buf);
|
||||||
ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, celt_word16);
|
ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, celt_word16);
|
||||||
|
|
||||||
pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, C);
|
pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC);
|
||||||
pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
|
pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
|
||||||
COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index);
|
COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index);
|
||||||
pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
|
pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
|
||||||
|
@ -1120,7 +1122,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
|
CELT_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
|
||||||
}
|
}
|
||||||
#endif /* ENABLE_POSTFILTER */
|
#endif /* ENABLE_POSTFILTER */
|
||||||
} while (++c<C);
|
} while (++c<CC);
|
||||||
|
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
}
|
}
|
||||||
|
@ -1137,7 +1139,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
{
|
{
|
||||||
if (st->complexity > 1)
|
if (st->complexity > 1)
|
||||||
{
|
{
|
||||||
isTransient = transient_analysis(in, N+st->overlap, C,
|
isTransient = transient_analysis(in, N+st->overlap, CC,
|
||||||
st->overlap);
|
st->overlap);
|
||||||
if (isTransient)
|
if (isTransient)
|
||||||
shortBlocks = M;
|
shortBlocks = M;
|
||||||
|
@ -1145,12 +1147,17 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
ec_enc_bit_logp(enc, isTransient, 3);
|
ec_enc_bit_logp(enc, isTransient, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
|
ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
|
||||||
ALLOC(bandE,st->mode->nbEBands*C, celt_ener);
|
ALLOC(bandE,st->mode->nbEBands*CC, celt_ener);
|
||||||
ALLOC(bandLogE,st->mode->nbEBands*C, celt_word16);
|
ALLOC(bandLogE,st->mode->nbEBands*CC, celt_word16);
|
||||||
/* Compute MDCTs */
|
/* Compute MDCTs */
|
||||||
compute_mdcts(st->mode, shortBlocks, in, freq, C, LM);
|
compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM);
|
||||||
|
|
||||||
|
if (CC==2&&C==1)
|
||||||
|
{
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
freq[i] = ADD32(HALF32(freq[i]), HALF32(freq[N+i]));
|
||||||
|
}
|
||||||
if (st->upsample != 1)
|
if (st->upsample != 1)
|
||||||
{
|
{
|
||||||
c=0; do
|
c=0; do
|
||||||
|
@ -1454,7 +1461,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
|
denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M);
|
||||||
|
|
||||||
CELT_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
|
CELT_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD);
|
||||||
if (C==2)
|
if (CC==2)
|
||||||
CELT_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
|
CELT_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD);
|
||||||
|
|
||||||
c=0; do
|
c=0; do
|
||||||
|
@ -1466,15 +1473,21 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
freq[c*N+i] = 0;
|
freq[c*N+i] = 0;
|
||||||
while (++c<C);
|
while (++c<C);
|
||||||
|
|
||||||
|
if (CC==2&&C==1)
|
||||||
|
{
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
freq[N+i] = freq[i];
|
||||||
|
}
|
||||||
|
|
||||||
out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
|
out_mem[0] = st->syn_mem[0]+MAX_PERIOD;
|
||||||
if (C==2)
|
if (CC==2)
|
||||||
out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
|
out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
|
||||||
|
|
||||||
c=0; do
|
c=0; do
|
||||||
overlap_mem[c] = _overlap_mem + c*st->overlap;
|
overlap_mem[c] = _overlap_mem + c*st->overlap;
|
||||||
while (++c<C);
|
while (++c<CC);
|
||||||
|
|
||||||
compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, C, LM);
|
compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM);
|
||||||
|
|
||||||
#ifdef ENABLE_POSTFILTER
|
#ifdef ENABLE_POSTFILTER
|
||||||
c=0; do {
|
c=0; do {
|
||||||
|
@ -1493,10 +1506,10 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
|
st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
|
||||||
st->mode->window, st->mode->overlap);
|
st->mode->window, st->mode->overlap);
|
||||||
}
|
}
|
||||||
} while (++c<C);
|
} while (++c<CC);
|
||||||
#endif /* ENABLE_POSTFILTER */
|
#endif /* ENABLE_POSTFILTER */
|
||||||
|
|
||||||
deemphasis(out_mem, (celt_word16*)pcm, N, C, st->upsample, st->mode->preemph, st->preemph_memD);
|
deemphasis(out_mem, (celt_word16*)pcm, N, CC, st->upsample, st->mode->preemph, st->preemph_memD);
|
||||||
st->prefilter_period_old = st->prefilter_period;
|
st->prefilter_period_old = st->prefilter_period;
|
||||||
st->prefilter_gain_old = st->prefilter_gain;
|
st->prefilter_gain_old = st->prefilter_gain;
|
||||||
st->prefilter_tapset_old = st->prefilter_tapset;
|
st->prefilter_tapset_old = st->prefilter_tapset;
|
||||||
|
@ -1507,6 +1520,11 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
st->prefilter_gain = gain1;
|
st->prefilter_gain = gain1;
|
||||||
st->prefilter_tapset = prefilter_tapset;
|
st->prefilter_tapset = prefilter_tapset;
|
||||||
|
|
||||||
|
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
|
||||||
{
|
{
|
||||||
|
@ -1514,15 +1532,15 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
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];
|
||||||
} 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]);
|
||||||
}
|
}
|
||||||
if (isTransient)
|
if (isTransient)
|
||||||
|
@ -1696,6 +1714,14 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
|
||||||
st->vbr_rate_norm = value>0?IMAX(1,((value<<(BITRES+3))+(frame_rate>>1))/frame_rate):0;
|
st->vbr_rate_norm = value>0?IMAX(1,((value<<(BITRES+3))+(frame_rate>>1))/frame_rate):0;
|
||||||
}
|
}
|
||||||
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->ENCODER_RESET_START, 0,
|
CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue