Adds in-band signalling of the CELT frame size and bandwidth
This commit is contained in:
parent
86da2c8b19
commit
e6acfe07cb
4 changed files with 86 additions and 31 deletions
|
@ -108,6 +108,7 @@ struct CELTEncoder {
|
|||
|
||||
celt_int32 bitrate;
|
||||
int vbr;
|
||||
int signalling;
|
||||
int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
|
||||
|
||||
/* Everything beyond this point gets cleared on a reset */
|
||||
|
@ -226,6 +227,8 @@ CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int
|
|||
st->upsample = 1;
|
||||
st->start = 0;
|
||||
st->end = st->mode->effEBands;
|
||||
st->signalling = 1;
|
||||
|
||||
st->constrained_vbr = 1;
|
||||
st->clip = 1;
|
||||
|
||||
|
@ -921,8 +924,6 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
|||
if (nbCompressedBytes<2 || pcm==NULL)
|
||||
return CELT_BAD_ARG;
|
||||
|
||||
/* Can't produce more than 1275 output bytes */
|
||||
nbCompressedBytes = IMIN(nbCompressedBytes,1275);
|
||||
frame_size *= st->upsample;
|
||||
for (LM=0;LM<=st->mode->maxLM;LM++)
|
||||
if (st->mode->shortMdctSize<<LM==frame_size)
|
||||
|
@ -947,12 +948,28 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
|||
tell=ec_tell(enc);
|
||||
nbFilledBytes=(tell+4)>>3;
|
||||
}
|
||||
|
||||
if (st->signalling && enc==NULL)
|
||||
{
|
||||
int tmp = (st->mode->effEBands-st->end)>>1;
|
||||
st->end = IMAX(1, st->mode->effEBands-tmp);
|
||||
compressed[0] = tmp<<5;
|
||||
compressed[0] |= LM<<3;
|
||||
compressed[0] |= (C==2)<<2;
|
||||
compressed++;
|
||||
nbCompressedBytes--;
|
||||
}
|
||||
|
||||
/* Can't produce more than 1275 output bytes */
|
||||
nbCompressedBytes = IMIN(nbCompressedBytes,1275);
|
||||
nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
|
||||
|
||||
if (st->vbr)
|
||||
{
|
||||
celt_int32 den=st->mode->Fs>>BITRES;
|
||||
vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
|
||||
if (st->signalling)
|
||||
vbr_rate -= 8<<BITRES;
|
||||
effectiveBytes = vbr_rate>>(3+BITRES);
|
||||
} else {
|
||||
celt_int32 tmp;
|
||||
|
@ -961,7 +978,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
|||
if (tell>1)
|
||||
tmp += tell;
|
||||
nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
|
||||
(tmp+4*st->mode->Fs)/(8*st->mode->Fs)));
|
||||
(tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling));
|
||||
effectiveBytes = nbCompressedBytes;
|
||||
}
|
||||
|
||||
|
@ -1604,6 +1621,9 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
|||
it's already filled with zeros */
|
||||
ec_enc_done(enc);
|
||||
|
||||
if (st->signalling)
|
||||
nbCompressedBytes++;
|
||||
|
||||
RESTORE_STACK;
|
||||
if (ec_get_error(enc))
|
||||
return CELT_CORRUPTED_DATA;
|
||||
|
@ -1759,6 +1779,11 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
|
|||
st->stream_channels = value;
|
||||
}
|
||||
break;
|
||||
case CELT_SET_SIGNALLING_REQUEST:
|
||||
{
|
||||
celt_int32 value = va_arg(ap, celt_int32);
|
||||
st->signalling = value;
|
||||
}
|
||||
case CELT_RESET_STATE:
|
||||
{
|
||||
CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
|
||||
|
@ -1807,6 +1832,7 @@ struct CELTDecoder {
|
|||
|
||||
int downsample;
|
||||
int start, end;
|
||||
int signalling;
|
||||
|
||||
/* Everything beyond this point gets cleared on a reset */
|
||||
#define DECODER_RESET_START rng
|
||||
|
@ -1907,6 +1933,7 @@ CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int
|
|||
st->downsample = 1;
|
||||
st->start = 0;
|
||||
st->end = st->mode->effEBands;
|
||||
st->signalling = 1;
|
||||
|
||||
st->loss_count = 0;
|
||||
|
||||
|
@ -2204,20 +2231,11 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
|||
int anti_collapse_rsv;
|
||||
int anti_collapse_on=0;
|
||||
int silence;
|
||||
const int C = CHANNELS(st->stream_channels);
|
||||
int C = CHANNELS(st->stream_channels);
|
||||
ALLOC_STACK;
|
||||
SAVE_STACK;
|
||||
|
||||
if (len<0 || len>1275 || pcm==NULL)
|
||||
return CELT_BAD_ARG;
|
||||
|
||||
frame_size *= st->downsample;
|
||||
for (LM=0;LM<=st->mode->maxLM;LM++)
|
||||
if (st->mode->shortMdctSize<<LM==frame_size)
|
||||
break;
|
||||
if (LM>st->mode->maxLM)
|
||||
return CELT_BAD_ARG;
|
||||
M=1<<LM;
|
||||
|
||||
c=0; do {
|
||||
decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
|
||||
|
@ -2230,6 +2248,31 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
|||
oldLogE2 = oldLogE + CC*st->mode->nbEBands;
|
||||
backgroundLogE = oldLogE2 + CC*st->mode->nbEBands;
|
||||
|
||||
if (st->signalling && data!=NULL)
|
||||
{
|
||||
st->end = IMAX(1, st->mode->effEBands-2*(data[0]>>5));
|
||||
LM = (data[0]>>3)&0x3;
|
||||
C = 1 + ((data[0]>>2)&0x1);
|
||||
data++;
|
||||
len--;
|
||||
if (LM>st->mode->maxLM)
|
||||
return CELT_CORRUPTED_DATA;
|
||||
if (frame_size < st->mode->shortMdctSize<<LM)
|
||||
return CELT_BAD_ARG;
|
||||
else
|
||||
frame_size = st->mode->shortMdctSize<<LM;
|
||||
} else {
|
||||
for (LM=0;LM<=st->mode->maxLM;LM++)
|
||||
if (st->mode->shortMdctSize<<LM==frame_size)
|
||||
break;
|
||||
if (LM>st->mode->maxLM)
|
||||
return CELT_BAD_ARG;
|
||||
}
|
||||
M=1<<LM;
|
||||
|
||||
if (len<0 || len>1275 || pcm==NULL)
|
||||
return CELT_BAD_ARG;
|
||||
|
||||
N = M*st->mode->shortMdctSize;
|
||||
|
||||
effEnd = st->end;
|
||||
|
@ -2258,7 +2301,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
|||
RESTORE_STACK;
|
||||
return CELT_BAD_ARG;
|
||||
}
|
||||
|
||||
|
||||
if (dec == NULL)
|
||||
{
|
||||
ec_dec_init(&_dec,(unsigned char*)data,len);
|
||||
|
@ -2510,7 +2553,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
|||
if (ec_tell(dec) > 8*len || ec_get_error(dec))
|
||||
return CELT_CORRUPTED_DATA;
|
||||
else
|
||||
return CELT_OK;
|
||||
return frame_size/st->downsample;
|
||||
}
|
||||
|
||||
#ifdef FIXED_POINT
|
||||
|
@ -2531,8 +2574,8 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
|
|||
|
||||
ALLOC(out, C*N, celt_int16);
|
||||
ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
|
||||
if (ret==0)
|
||||
for (j=0;j<C*N;j++)
|
||||
if (ret>0)
|
||||
for (j=0;j<C*ret;j++)
|
||||
pcm[j]=out[j]*(1.f/32768.f);
|
||||
|
||||
RESTORE_STACK;
|
||||
|
@ -2557,8 +2600,8 @@ int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, in
|
|||
|
||||
ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
|
||||
|
||||
if (ret==0)
|
||||
for (j=0;j<C*N;j++)
|
||||
if (ret>0)
|
||||
for (j=0;j<C*ret;j++)
|
||||
pcm[j] = FLOAT2INT16 (out[j]);
|
||||
|
||||
RESTORE_STACK;
|
||||
|
@ -2616,6 +2659,11 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
|
|||
goto bad_arg;
|
||||
st->stream_channels = value;
|
||||
}
|
||||
case CELT_SET_SIGNALLING_REQUEST:
|
||||
{
|
||||
celt_int32 value = va_arg(ap, celt_int32);
|
||||
st->signalling = value;
|
||||
}
|
||||
break;
|
||||
case CELT_RESET_STATE:
|
||||
{
|
||||
|
|
|
@ -113,6 +113,9 @@ extern "C" {
|
|||
#define CELT_SET_CHANNELS_REQUEST 10002
|
||||
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_SIGNALLING_REQUEST 10003
|
||||
#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, _celt_check_int(x)
|
||||
|
||||
/** GET the lookahead used in the current mode */
|
||||
#define CELT_GET_LOOKAHEAD 1001
|
||||
/** GET the sample rate used in the current mode */
|
||||
|
|
|
@ -644,10 +644,13 @@ kiss_fft_state *kiss_fft_alloc(int nfft,void * mem,size_t * lenmem )
|
|||
|
||||
void kiss_fft_free(const kiss_fft_state *cfg)
|
||||
{
|
||||
celt_free((celt_int16*)cfg->bitrev);
|
||||
if (cfg->shift < 0)
|
||||
celt_free((kiss_twiddle_cpx*)cfg->twiddles);
|
||||
celt_free((kiss_fft_state*)cfg);
|
||||
if (cfg)
|
||||
{
|
||||
celt_free((celt_int16*)cfg->bitrev);
|
||||
if (cfg->shift < 0)
|
||||
celt_free((kiss_twiddle_cpx*)cfg->twiddles);
|
||||
celt_free((kiss_fft_state*)cfg);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CUSTOM_MODES */
|
||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char *argv[])
|
|||
unsigned char data[MAX_PACKET];
|
||||
int rate;
|
||||
int complexity;
|
||||
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES))
|
||||
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
|
||||
int i;
|
||||
double rmsd = 0;
|
||||
#endif
|
||||
|
@ -126,6 +126,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
while (!feof(fin))
|
||||
{
|
||||
int ret;
|
||||
err = fread(in, sizeof(short), frame_size*channels, fin);
|
||||
if (feof(fin))
|
||||
break;
|
||||
|
@ -160,24 +161,24 @@ int main(int argc, char *argv[])
|
|||
/* This is to simulate packet loss */
|
||||
if (argc==9 && rand()%1000<atoi(argv[argc-3]))
|
||||
/*if (errors && (errors%2==0))*/
|
||||
err = celt_decode(dec, NULL, len, out, frame_size);
|
||||
ret = celt_decode(dec, NULL, len, out, frame_size);
|
||||
else
|
||||
err = celt_decode(dec, data, len, out, frame_size);
|
||||
if (err != 0)
|
||||
fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(err));
|
||||
ret = celt_decode(dec, data, len, out, frame_size);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(ret));
|
||||
#else
|
||||
for (i=0;i<frame_size*channels;i++)
|
||||
for (i=0;i<ret*channels;i++)
|
||||
out[i] = in[i];
|
||||
#endif
|
||||
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
|
||||
for (i=0;i<frame_size*channels;i++)
|
||||
for (i=0;i<ret*channels;i++)
|
||||
{
|
||||
rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);
|
||||
/*out[i] -= in[i];*/
|
||||
}
|
||||
#endif
|
||||
count++;
|
||||
fwrite(out+skip*channels, sizeof(short), (frame_size-skip)*channels, fout);
|
||||
fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
|
||||
skip = 0;
|
||||
}
|
||||
PRINT_MIPS(stderr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue