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;
|
celt_int32 bitrate;
|
||||||
int vbr;
|
int vbr;
|
||||||
|
int signalling;
|
||||||
int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
|
int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
|
||||||
|
|
||||||
/* Everything beyond this point gets cleared on a reset */
|
/* 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->upsample = 1;
|
||||||
st->start = 0;
|
st->start = 0;
|
||||||
st->end = st->mode->effEBands;
|
st->end = st->mode->effEBands;
|
||||||
|
st->signalling = 1;
|
||||||
|
|
||||||
st->constrained_vbr = 1;
|
st->constrained_vbr = 1;
|
||||||
st->clip = 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)
|
if (nbCompressedBytes<2 || pcm==NULL)
|
||||||
return CELT_BAD_ARG;
|
return CELT_BAD_ARG;
|
||||||
|
|
||||||
/* Can't produce more than 1275 output bytes */
|
|
||||||
nbCompressedBytes = IMIN(nbCompressedBytes,1275);
|
|
||||||
frame_size *= st->upsample;
|
frame_size *= st->upsample;
|
||||||
for (LM=0;LM<=st->mode->maxLM;LM++)
|
for (LM=0;LM<=st->mode->maxLM;LM++)
|
||||||
if (st->mode->shortMdctSize<<LM==frame_size)
|
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);
|
tell=ec_tell(enc);
|
||||||
nbFilledBytes=(tell+4)>>3;
|
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;
|
nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
|
||||||
|
|
||||||
if (st->vbr)
|
if (st->vbr)
|
||||||
{
|
{
|
||||||
celt_int32 den=st->mode->Fs>>BITRES;
|
celt_int32 den=st->mode->Fs>>BITRES;
|
||||||
vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
|
vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
|
||||||
|
if (st->signalling)
|
||||||
|
vbr_rate -= 8<<BITRES;
|
||||||
effectiveBytes = vbr_rate>>(3+BITRES);
|
effectiveBytes = vbr_rate>>(3+BITRES);
|
||||||
} else {
|
} else {
|
||||||
celt_int32 tmp;
|
celt_int32 tmp;
|
||||||
|
@ -961,7 +978,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
|
||||||
if (tell>1)
|
if (tell>1)
|
||||||
tmp += tell;
|
tmp += tell;
|
||||||
nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
|
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;
|
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 */
|
it's already filled with zeros */
|
||||||
ec_enc_done(enc);
|
ec_enc_done(enc);
|
||||||
|
|
||||||
|
if (st->signalling)
|
||||||
|
nbCompressedBytes++;
|
||||||
|
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
if (ec_get_error(enc))
|
if (ec_get_error(enc))
|
||||||
return CELT_CORRUPTED_DATA;
|
return CELT_CORRUPTED_DATA;
|
||||||
|
@ -1759,6 +1779,11 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
|
||||||
st->stream_channels = value;
|
st->stream_channels = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CELT_SET_SIGNALLING_REQUEST:
|
||||||
|
{
|
||||||
|
celt_int32 value = va_arg(ap, celt_int32);
|
||||||
|
st->signalling = value;
|
||||||
|
}
|
||||||
case CELT_RESET_STATE:
|
case CELT_RESET_STATE:
|
||||||
{
|
{
|
||||||
CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
|
CELT_MEMSET((char*)&st->ENCODER_RESET_START, 0,
|
||||||
|
@ -1807,6 +1832,7 @@ struct CELTDecoder {
|
||||||
|
|
||||||
int downsample;
|
int downsample;
|
||||||
int start, end;
|
int start, end;
|
||||||
|
int signalling;
|
||||||
|
|
||||||
/* Everything beyond this point gets cleared on a reset */
|
/* Everything beyond this point gets cleared on a reset */
|
||||||
#define DECODER_RESET_START rng
|
#define DECODER_RESET_START rng
|
||||||
|
@ -1907,6 +1933,7 @@ CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int
|
||||||
st->downsample = 1;
|
st->downsample = 1;
|
||||||
st->start = 0;
|
st->start = 0;
|
||||||
st->end = st->mode->effEBands;
|
st->end = st->mode->effEBands;
|
||||||
|
st->signalling = 1;
|
||||||
|
|
||||||
st->loss_count = 0;
|
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_rsv;
|
||||||
int anti_collapse_on=0;
|
int anti_collapse_on=0;
|
||||||
int silence;
|
int silence;
|
||||||
const int C = CHANNELS(st->stream_channels);
|
int C = CHANNELS(st->stream_channels);
|
||||||
ALLOC_STACK;
|
ALLOC_STACK;
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
|
|
||||||
if (len<0 || len>1275 || pcm==NULL)
|
|
||||||
return CELT_BAD_ARG;
|
|
||||||
|
|
||||||
frame_size *= st->downsample;
|
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 {
|
c=0; do {
|
||||||
decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
|
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;
|
oldLogE2 = oldLogE + CC*st->mode->nbEBands;
|
||||||
backgroundLogE = oldLogE2 + 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;
|
N = M*st->mode->shortMdctSize;
|
||||||
|
|
||||||
effEnd = st->end;
|
effEnd = st->end;
|
||||||
|
@ -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))
|
if (ec_tell(dec) > 8*len || ec_get_error(dec))
|
||||||
return CELT_CORRUPTED_DATA;
|
return CELT_CORRUPTED_DATA;
|
||||||
else
|
else
|
||||||
return CELT_OK;
|
return frame_size/st->downsample;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#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);
|
ALLOC(out, C*N, celt_int16);
|
||||||
ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
|
ret=celt_decode_with_ec(st, data, len, out, frame_size, dec);
|
||||||
if (ret==0)
|
if (ret>0)
|
||||||
for (j=0;j<C*N;j++)
|
for (j=0;j<C*ret;j++)
|
||||||
pcm[j]=out[j]*(1.f/32768.f);
|
pcm[j]=out[j]*(1.f/32768.f);
|
||||||
|
|
||||||
RESTORE_STACK;
|
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);
|
ret=celt_decode_with_ec_float(st, data, len, out, frame_size, dec);
|
||||||
|
|
||||||
if (ret==0)
|
if (ret>0)
|
||||||
for (j=0;j<C*N;j++)
|
for (j=0;j<C*ret;j++)
|
||||||
pcm[j] = FLOAT2INT16 (out[j]);
|
pcm[j] = FLOAT2INT16 (out[j]);
|
||||||
|
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
|
@ -2616,6 +2659,11 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
|
||||||
goto bad_arg;
|
goto bad_arg;
|
||||||
st->stream_channels = value;
|
st->stream_channels = value;
|
||||||
}
|
}
|
||||||
|
case CELT_SET_SIGNALLING_REQUEST:
|
||||||
|
{
|
||||||
|
celt_int32 value = va_arg(ap, celt_int32);
|
||||||
|
st->signalling = value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CELT_RESET_STATE:
|
case CELT_RESET_STATE:
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,6 +113,9 @@ extern "C" {
|
||||||
#define CELT_SET_CHANNELS_REQUEST 10002
|
#define CELT_SET_CHANNELS_REQUEST 10002
|
||||||
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, _celt_check_int(x)
|
#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 */
|
/** 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 */
|
||||||
|
|
|
@ -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)
|
void kiss_fft_free(const kiss_fft_state *cfg)
|
||||||
{
|
{
|
||||||
|
if (cfg)
|
||||||
|
{
|
||||||
celt_free((celt_int16*)cfg->bitrev);
|
celt_free((celt_int16*)cfg->bitrev);
|
||||||
if (cfg->shift < 0)
|
if (cfg->shift < 0)
|
||||||
celt_free((kiss_twiddle_cpx*)cfg->twiddles);
|
celt_free((kiss_twiddle_cpx*)cfg->twiddles);
|
||||||
celt_free((kiss_fft_state*)cfg);
|
celt_free((kiss_fft_state*)cfg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CUSTOM_MODES */
|
#endif /* CUSTOM_MODES */
|
||||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char *argv[])
|
||||||
unsigned char data[MAX_PACKET];
|
unsigned char data[MAX_PACKET];
|
||||||
int rate;
|
int rate;
|
||||||
int complexity;
|
int complexity;
|
||||||
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES))
|
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
|
||||||
int i;
|
int i;
|
||||||
double rmsd = 0;
|
double rmsd = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,6 +126,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while (!feof(fin))
|
while (!feof(fin))
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
err = fread(in, sizeof(short), frame_size*channels, fin);
|
err = fread(in, sizeof(short), frame_size*channels, fin);
|
||||||
if (feof(fin))
|
if (feof(fin))
|
||||||
break;
|
break;
|
||||||
|
@ -160,24 +161,24 @@ int main(int argc, char *argv[])
|
||||||
/* This is to simulate packet loss */
|
/* This is to simulate packet loss */
|
||||||
if (argc==9 && rand()%1000<atoi(argv[argc-3]))
|
if (argc==9 && rand()%1000<atoi(argv[argc-3]))
|
||||||
/*if (errors && (errors%2==0))*/
|
/*if (errors && (errors%2==0))*/
|
||||||
err = celt_decode(dec, NULL, len, out, frame_size);
|
ret = celt_decode(dec, NULL, len, out, frame_size);
|
||||||
else
|
else
|
||||||
err = celt_decode(dec, data, len, out, frame_size);
|
ret = celt_decode(dec, data, len, out, frame_size);
|
||||||
if (err != 0)
|
if (ret < 0)
|
||||||
fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(err));
|
fprintf(stderr, "celt_decode() failed: %s\n", celt_strerror(ret));
|
||||||
#else
|
#else
|
||||||
for (i=0;i<frame_size*channels;i++)
|
for (i=0;i<ret*channels;i++)
|
||||||
out[i] = in[i];
|
out[i] = in[i];
|
||||||
#endif
|
#endif
|
||||||
#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
|
#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]);
|
rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);
|
||||||
/*out[i] -= in[i];*/
|
/*out[i] -= in[i];*/
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
count++;
|
count++;
|
||||||
fwrite(out+skip*channels, sizeof(short), (frame_size-skip)*channels, fout);
|
fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
|
||||||
skip = 0;
|
skip = 0;
|
||||||
}
|
}
|
||||||
PRINT_MIPS(stderr);
|
PRINT_MIPS(stderr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue