ref: e6acfe07cbf7193305f1a9eef43f44f1ee207235
parent: 86da2c8b19134b84d408c4fda583abab4bcc2219
author: Jean-Marc Valin <[email protected]>
date: Fri Mar 11 11:31:24 EST 2011
Adds in-band signalling of the CELT frame size and bandwidth
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -108,6 +108,7 @@
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 @@
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 @@
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,6 +948,20 @@
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)
@@ -953,6 +968,8 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
st->downsample = 1;
st->start = 0;
st->end = st->mode->effEBands;
+ st->signalling = 1;
st->loss_count = 0;
@@ -2204,20 +2231,11 @@
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 @@
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 @@
RESTORE_STACK;
return CELT_BAD_ARG;
}
-
+
if (dec == NULL)
{
ec_dec_init(&_dec,(unsigned char*)data,len);
@@ -2510,7 +2553,7 @@
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 @@
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 @@
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;
@@ -2615,6 +2658,11 @@
if (value<1 || value>2)
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:
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -113,6 +113,9 @@
#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 */
--- a/libcelt/kiss_fft.c
+++ b/libcelt/kiss_fft.c
@@ -644,10 +644,13 @@
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 */
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -53,7 +53,7 @@
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 @@
while (!feof(fin))
{
+ int ret;
err = fread(in, sizeof(short), frame_size*channels, fin);
if (feof(fin))
break;
@@ -160,17 +161,17 @@
/* 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];*/
@@ -177,7 +178,7 @@
}
#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);