ref: 06cee2b1b46d9e15d7a141fce1b76933429c076e
parent: 06677d73682e7bb60651ae4860841ab5e45c6904
author: Jean-Marc Valin <[email protected]>
date: Fri Aug 19 12:11:41 EDT 2011
Including redundant frames in the final range coder state
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -1838,6 +1838,14 @@
*value=st->mode;
}
break;
+ case CELT_GET_RANGE_REQUEST:
+ {
+ opus_uint32 * value = va_arg(ap, opus_uint32 *);
+ if (value==0)
+ goto bad_arg;
+ *value=st->rng;
+ }
+ break;
#endif
default:
goto bad_request;
@@ -2739,6 +2747,14 @@
{
opus_int32 value = va_arg(ap, opus_int32);
st->signalling = value;
+ }
+ break;
+ case CELT_GET_RANGE_REQUEST:
+ {
+ opus_uint32 * value = va_arg(ap, opus_uint32 *);
+ if (value==0)
+ goto bad_arg;
+ *value=st->rng;
}
break;
#endif
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -51,7 +51,8 @@
#define _celt_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
-#define _celt_check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr)))
+#define _celt_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
+#define _celt_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
/* Error codes */
/** No error */
@@ -120,6 +121,9 @@
#define CELT_SET_END_BAND_REQUEST 10001
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
+
+#define CELT_GET_RANGE_REQUEST 10002
+#define CELT_GET_RANGE(x) CELT_GET_RANGE_REQUEST, _celt_check_uint_ptr(x)
/** Contains the state of an encoder. One encoder state is needed
for each stream. It is initialised once at the beginning of the
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -196,6 +196,7 @@
int c;
int F2_5, F5, F10, F20;
const opus_val16 *window;
+ opus_uint32 redundant_rng = 0;
ALLOC_STACK;
silk_dec = (char*)st+st->silk_dec_offset;
@@ -373,6 +374,7 @@
{
celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_native(celt_dec, data+len, redundancy_bytes, redundant_audio, F5);
+ celt_decoder_ctl(celt_dec, CELT_GET_RANGE(&redundant_rng));
celt_decoder_ctl(celt_dec, CELT_RESET_STATE);
}
@@ -416,6 +418,7 @@
celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_native(celt_dec, data+len, redundancy_bytes, redundant_audio, F5);
+ celt_decoder_ctl(celt_dec, CELT_GET_RANGE(&redundant_rng));
smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
}
@@ -439,7 +442,7 @@
st->channels, window, st->Fs);
}
- st->rangeFinal = dec.rng;
+ st->rangeFinal = dec.rng ^ redundant_rng;
st->prev_mode = mode;
st->prev_redundancy = redundancy;
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -258,6 +258,7 @@
int nb_compr_bytes;
int to_celt = 0;
opus_int32 mono_rate;
+ opus_uint32 redundant_rng = 0;
ALLOC_STACK;
if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
@@ -685,6 +686,7 @@
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
celt_encoder_ctl(celt_enc, CELT_SET_VBR(0));
celt_encode_native(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
+ celt_encoder_ctl(celt_enc, CELT_GET_RANGE(&redundant_rng));
celt_encoder_ctl(celt_enc, CELT_RESET_STATE);
}
@@ -710,6 +712,7 @@
celt_encode_native(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
celt_encode_native(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
+ celt_encoder_ctl(celt_enc, CELT_GET_RANGE(&redundant_rng));
}
@@ -729,7 +732,7 @@
data--;
data[0] = gen_toc(st->mode, st->Fs/frame_size, st->bandwidth, st->stream_channels);
- st->rangeFinal = enc.rng;
+ st->rangeFinal = enc.rng ^ redundant_rng;
if (to_celt)
st->prev_mode = MODE_CELT_ONLY;