diff --git a/libcelt/celt.c b/libcelt/celt.c
index b07e682be72de61e7f724367d4c9aa9743779c82..884edee0f4e2b9d8a81b17bed36f3dee78b754d8 100644
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -866,6 +866,23 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
          st->VBR_rate = ((value<<7)+(st->VBR_rate>>1))/st->VBR_rate;
       }
       break;
+      case CELT_RESET_STATE:
+      {
+         const CELTMode *mode = st->mode;
+         int C = mode->nbChannels;
+
+         if (st->pitch_available > 0) st->pitch_available = 1;
+
+         CELT_MEMSET(st->in_mem, 0, st->overlap*C);
+         CELT_MEMSET(st->out_mem, 0, (MAX_PERIOD+st->overlap)*C);
+
+         CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
+
+         CELT_MEMSET(st->preemph_memE, 0, C);
+         CELT_MEMSET(st->preemph_memD, 0, C);
+         st->delayedIntra = 1;
+      }
+      break;
       default:
          goto bad_request;
    }
@@ -1220,3 +1237,37 @@ int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, c
    return ret;
 }
 #endif
+
+int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
+{
+   va_list ap;
+   va_start(ap, request);
+   switch (request)
+   {
+      case CELT_RESET_STATE:
+      {
+         const CELTMode *mode = st->mode;
+         int C = mode->nbChannels;
+
+         CELT_MEMSET(st->decode_mem, 0, (DECODE_BUFFER_SIZE+st->overlap)*C);
+         CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
+
+         CELT_MEMSET(st->preemph_memD, 0, C);
+
+         st->last_pitch_index = 0;
+      }
+      break;
+      default:
+         goto bad_request;
+   }
+   va_end(ap);
+   return CELT_OK;
+#if 0    /* Put this back in if you ever need "bad_arg" */
+bad_arg:
+   va_end(ap);
+   return CELT_BAD_ARG;
+#endif
+bad_request:
+      va_end(ap);
+  return CELT_UNIMPLEMENTED;
+}
diff --git a/libcelt/celt.h b/libcelt/celt.h
index a162c91cde40a132f55e8847bc6b3199b42fd06b..31520500266410f8be6b75982d9a1b15dcfad3c7 100644
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -77,6 +77,9 @@ extern "C" {
 #define CELT_SET_VBR_RATE_REQUEST    6
 /** Set the target VBR rate in bits per second (int); 0=CBR (default) */
 #define CELT_SET_VBR_RATE(x) CELT_SET_VBR_RATE_REQUEST, _celt_check_int(x)
+/** Reset the encoder/decoder memories to zero*/
+#define CELT_RESET_STATE_REQUEST        8
+#define CELT_RESET_STATE       CELT_RESET_STATE_REQUEST
 
 /** GET the frame size used in the current mode */
 #define CELT_GET_FRAME_SIZE   1000
@@ -238,6 +241,15 @@ EXPORT int celt_decode_float(CELTDecoder *st, const unsigned char *data, int len
  */
 EXPORT int celt_decode(CELTDecoder *st, const unsigned char *data, int len, celt_int16_t *pcm);
 
+/** Query and set decoder parameters
+   @param st Decoder state
+   @param request Parameter to change or query
+   @param value Pointer to a 32-bit int value
+   @return Error code
+ */
+EXPORT int celt_decoder_ctl(CELTDecoder * st, int request, ...);
+
+
 /*  @} */