summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2011-08-30 18:01:06 -0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2011-08-30 18:01:06 -0400
commit04465630101689dce30193ecc0476490a20116e5 (patch)
tree85eaee46d2919f2608ed23785833d45c0c118282
parentec8008b086d39901c469386c0506c61ffd8a9ae4 (diff)
downloadopus-04465630101689dce30193ecc0476490a20116e5.tar.gz
Implements OPUS_RESET_STATE for the decoder (untested)
-rw-r--r--src/opus.h2
-rw-r--r--src/opus_decoder.c37
2 files changed, 30 insertions, 9 deletions
diff --git a/src/opus.h b/src/opus.h
index fb49b0b1..20a01afe 100644
--- a/src/opus.h
+++ b/src/opus.h
@@ -157,6 +157,8 @@ extern "C" {
#define OPUS_GET_LOOKAHEAD_REQUEST 27
#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x)
+#define OPUS_RESET_STATE 28
+
/* For testing purposes: the encoder and decoder state should
always be identical after coding a payload */
#define OPUS_GET_FINAL_RANGE_REQUEST 29
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 074b9d6e..9f10554c 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -50,17 +50,19 @@ struct OpusDecoder {
int celt_dec_offset;
int silk_dec_offset;
int channels;
+ int Fs; /** Sampling rate (at the API level) */
+
+ /* Everything beyond this point gets cleared on a reset */
+#define OPUS_DECODER_RESET_START stream_channels
int stream_channels;
- int bandwidth;
- /* Sampling rate (at the API level) */
- int Fs;
- int mode;
- int prev_mode;
- int frame_size;
- int prev_redundancy;
+ int bandwidth;
+ int mode;
+ int prev_mode;
+ int frame_size;
+ int prev_redundancy;
- int rangeFinal;
+ int rangeFinal;
};
#ifdef FIXED_POINT
@@ -216,7 +218,6 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
{
data = NULL;
/* In that case, don't conceal more than what the ToC says */
- /* FIXME: What if st->frame_size has never been set? */
frame_size = IMIN(frame_size, st->frame_size);
}
if (data != NULL)
@@ -759,6 +760,24 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
*value = st->rangeFinal;
}
break;
+ case OPUS_RESET_STATE:
+ {
+ void *silk_dec;
+ CELTDecoder *celt_dec;
+
+ silk_dec = (char*)st+st->silk_dec_offset;
+ celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
+
+ OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
+ opus_decoder_get_size(st->channels)-
+ ((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
+
+ celt_decoder_ctl(celt_dec, CELT_RESET_STATE);
+ silk_InitDecoder( silk_dec );
+ st->stream_channels = st->channels;
+ st->frame_size = st->Fs/400;
+ }
+ break;
default:
/*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
ret = OPUS_BAD_ARG;