Merge third_party/opus/src from https://chromium.googlesource.com/chromium/deps/opus.git at 6b6bee25314cfac02cc555cddedb9680c63a26d6

This commit was generated by merge_from_chromium.py.

Change-Id: I21d8ae69c1a3c4d1df13015f82099a7d6422678e
diff --git a/COPYING b/COPYING
index 3167a00..f4159e6 100644
--- a/COPYING
+++ b/COPYING
@@ -37,8 +37,8 @@
 Xiph.Org Foundation:
 https://datatracker.ietf.org/ipr/1524/
 
-Skype Limited:
-https://datatracker.ietf.org/ipr/1602/
+Microsoft Corporation:
+https://datatracker.ietf.org/ipr/1914/
 
 Broadcom Corporation:
 https://datatracker.ietf.org/ipr/1526/
diff --git a/Makefile.am b/Makefile.am
index db37d99..85909ce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,24 +126,24 @@
 
 # Or just the docs
 docs:
-	cd doc && $(MAKE) $(AM_MAKEFLAGS)
+	( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
 
 install-docs:
-	cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+	( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
 
 
 # Or everything (by default)
 all-local:
-	@[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS)
+	@[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
 
 install-data-local:
-	@[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+	@[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
 
 clean-local:
-	-cd doc && $(MAKE) $(AM_MAKEFLAGS) clean
+	-( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean )
 
 uninstall-local:
-	cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall
+	( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall )
 
 
 .PHONY: opus check-opus install-opus docs install-docs
diff --git a/Makefile.in b/Makefile.in
index 07cb8eb..38b5021 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -19,6 +19,23 @@
 
 
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -405,6 +422,11 @@
 	install-pdf-recursive install-ps-recursive install-recursive \
 	installcheck-recursive installdirs-recursive pdf-recursive \
 	ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DATA = $(m4data_DATA) $(pkgconfig_DATA)
 am__pkginclude_HEADERS_DIST = include/opus.h \
 	include/opus_multistream.h include/opus_types.h \
@@ -522,6 +544,8 @@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PC_BUILD = @PC_BUILD@
+PC_LIBM = @PC_LIBM@
 RANLIB = @RANLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
@@ -894,7 +918,6 @@
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
 	@$(NORMAL_INSTALL)
-	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
 	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
 	list2=; for p in $$list; do \
 	  if test -f $$p; then \
@@ -902,6 +925,8 @@
 	  else :; fi; \
 	done; \
 	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
 	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
 	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
 	}
@@ -1861,8 +1886,11 @@
 	-rm -f libtool config.lt
 install-m4dataDATA: $(m4data_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)"
 	@list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -1879,8 +1907,11 @@
 	dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
 install-pkgconfigDATA: $(pkgconfig_DATA)
 	@$(NORMAL_INSTALL)
-	test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
 	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -1897,8 +1928,11 @@
 	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
 install-pkgincludeHEADERS: $(pkginclude_HEADERS)
 	@$(NORMAL_INSTALL)
-	test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
 	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
+	fi; \
 	for p in $$list; do \
 	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
 	  echo "$$d$$p"; \
@@ -2176,13 +2210,10 @@
 	done
 	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
 	  if test "$$subdir" = .; then :; else \
-	    test -d "$(distdir)/$$subdir" \
-	    || $(MKDIR_P) "$(distdir)/$$subdir" \
-	    || exit 1; \
-	  fi; \
-	done
-	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
-	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
 	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
 	    $(am__relativize); \
 	    new_distdir=$$reldir; \
@@ -2268,7 +2299,7 @@
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
 	esac
-	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	chmod -R a-w $(distdir); chmod u+w $(distdir)
 	mkdir $(distdir)/_build
 	mkdir $(distdir)/_inst
 	chmod a-w $(distdir)
@@ -2499,23 +2530,23 @@
 
 # Or just the docs
 docs:
-	cd doc && $(MAKE) $(AM_MAKEFLAGS)
+	( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
 
 install-docs:
-	cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+	( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
 
 # Or everything (by default)
 all-local:
-	@[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS)
+	@[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) )
 
 install-data-local:
-	@[ -n "$(NO_DOXYGEN)" ] || cd doc && $(MAKE) $(AM_MAKEFLAGS) install
+	@[ -n "$(NO_DOXYGEN)" ] || ( cd doc && $(MAKE) $(AM_MAKEFLAGS) install )
 
 clean-local:
-	-cd doc && $(MAKE) $(AM_MAKEFLAGS) clean
+	-( cd doc && $(MAKE) $(AM_MAKEFLAGS) clean )
 
 uninstall-local:
-	cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall
+	( cd doc && $(MAKE) $(AM_MAKEFLAGS) uninstall )
 
 .PHONY: opus check-opus install-opus docs install-docs
 
diff --git a/README b/README
index ea68fe3..655c6b4 100644
--- a/README
+++ b/README
@@ -59,6 +59,10 @@
 % ./configure
 % make
 
+3) Install the codec libraries (optional)
+
+% sudo make install
+
 Once you have compiled the codec, there will be a opus_demo executable
 in the top directory.
 
diff --git a/aclocal.m4 b/aclocal.m4
index 6158f7b..3b2c931 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 # 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
@@ -8629,7 +8629,7 @@
 [am__api_version='1.11'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.11.3], [],
+m4_if([$1], [1.11.6], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -8645,7 +8645,7 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.3])dnl
+[AM_AUTOMAKE_VERSION([1.11.6])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
diff --git a/celt/bands.c b/celt/bands.c
index f38b662..3be543c 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -905,8 +905,8 @@
          fill &= ((1<<B)-1)<<B;
          delta = 16384;
       } else {
-         imid = bitexact_cos(itheta);
-         iside = bitexact_cos(16384-itheta);
+         imid = bitexact_cos((opus_int16)itheta);
+         iside = bitexact_cos((opus_int16)(16384-itheta));
          /* This is the mid vs side allocation that minimizes squared error
             in that band. */
          delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
diff --git a/celt/celt.c b/celt/celt.c
index adb9737..9bbe852 100644
--- a/celt/celt.c
+++ b/celt/celt.c
@@ -193,9 +193,13 @@
 #endif
 
    celt_sig in_mem[1]; /* Size = channels*mode->overlap */
-   /* celt_sig prefilter_mem[],  Size = channels*COMBFILTER_PERIOD */
-   /* celt_sig overlap_mem[],  Size = channels*mode->overlap */
-   /* opus_val16 oldEBands[], Size = 2*channels*mode->nbEBands */
+   /* celt_sig prefilter_mem[],  Size = channels*COMBFILTER_MAXPERIOD */
+   /* opus_val16 oldBandE[],     Size = channels*mode->nbEBands */
+   /* opus_val16 oldLogE[],      Size = channels*mode->nbEBands */
+   /* opus_val16 oldLogE2[],     Size = channels*mode->nbEBands */
+#ifdef RESYNTH
+   /* opus_val16 overlap_mem[],  Size = channels*overlap */
+#endif
 };
 
 int celt_encoder_get_size(int channels)
@@ -207,9 +211,14 @@
 OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels)
 {
    int size = sizeof(struct CELTEncoder)
-         + (2*channels*mode->overlap-1)*sizeof(celt_sig)
-         + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig)
-         + 3*channels*mode->nbEBands*sizeof(opus_val16);
+         + (channels*mode->overlap-1)*sizeof(celt_sig)    /* celt_sig in_mem[channels*mode->overlap]; */
+         + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */
+         + 3*channels*mode->nbEBands*sizeof(opus_val16);  /* opus_val16 oldBandE[channels*mode->nbEBands]; */
+                                                          /* opus_val16 oldLogE[channels*mode->nbEBands]; */
+                                                          /* opus_val16 oldLogE2[channels*mode->nbEBands]; */
+#ifdef RESYNTH
+   size += channels*mode->overlap*sizeof(celt_sig);       /* celt_sig overlap_mem[channels*mode->nbEBands]; */
+#endif
    return size;
 }
 
@@ -563,7 +572,7 @@
 
 static int tf_analysis(const CELTMode *m, int len, int C, int isTransient,
       int *tf_res, int nbCompressedBytes, celt_norm *X, int N0, int LM,
-      int *tf_sum)
+      int start, int *tf_sum)
 {
    int i;
    VARDECL(int, metric);
@@ -576,7 +585,7 @@
    int tf_select=0;
    SAVE_STACK;
 
-   if (nbCompressedBytes<15*C)
+   if (nbCompressedBytes<15*C || start!=0)
    {
       *tf_sum = 0;
       for (i=0;i<len;i++)
@@ -944,7 +953,7 @@
    N = M*st->mode->shortMdctSize;
 
    prefilter_mem = st->in_mem+CC*(st->overlap);
-   oldBandE = (opus_val16*)(st->in_mem+CC*(2*st->overlap+COMBFILTER_MAXPERIOD));
+   oldBandE = (opus_val16*)(st->in_mem+CC*(st->overlap+COMBFILTER_MAXPERIOD));
    oldLogE = oldBandE + CC*st->mode->nbEBands;
    oldLogE2 = oldLogE + CC*st->mode->nbEBands;
 
@@ -1266,7 +1275,7 @@
    normalise_bands(st->mode, freq, X, bandE, effEnd, C, M);
 
    ALLOC(tf_res, st->mode->nbEBands, int);
-   tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, &tf_sum);
+   tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, st->start, &tf_sum);
    for (i=effEnd;i<st->end;i++)
       tf_res[i] = tf_res[effEnd-1];
 
@@ -1278,13 +1287,15 @@
 
    tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
 
-   st->spread_decision = SPREAD_NORMAL;
    if (ec_tell(enc)+4<=total_bits)
    {
-      if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
+      if (shortBlocks || st->complexity < 3 
+          || nbAvailableBytes < 10*C || st->start!=0)
       {
          if (st->complexity == 0)
             st->spread_decision = SPREAD_NONE;
+         else
+            st->spread_decision = SPREAD_NORMAL;
       } else {
          st->spread_decision = spreading_decision(st->mode, X,
                &st->tonal_average, st->spread_decision, &st->hf_average,
@@ -1588,7 +1599,7 @@
       if (CC==2)
          out_mem[1] = st->syn_mem[1]+MAX_PERIOD;
 
-      overlap_mem[0] = prefilter_mem+CC*COMBFILTER_MAXPERIOD;
+      overlap_mem[0] = (celt_sig*)(oldLogE2 + CC*st->mode->nbEBands);
       if (CC==2)
          overlap_mem[1] = overlap_mem[0] + st->overlap;
 
@@ -1843,7 +1854,7 @@
       {
          int i;
          opus_val16 *oldBandE, *oldLogE, *oldLogE2;
-         oldBandE = (opus_val16*)(st->in_mem+st->channels*(2*st->overlap+COMBFILTER_MAXPERIOD));
+         oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->overlap+COMBFILTER_MAXPERIOD));
          oldLogE = oldBandE + st->channels*st->mode->nbEBands;
          oldLogE2 = oldLogE + st->channels*st->mode->nbEBands;
          OPUS_CLEAR((char*)&st->ENCODER_RESET_START,
@@ -2028,7 +2039,6 @@
 {
    int c;
    int pitch_index;
-   int overlap = st->mode->overlap;
    opus_val16 fade = Q15ONE;
    int i, len;
    const int C = st->channels;
@@ -2039,8 +2049,17 @@
    opus_val16 *lpc;
    opus_val32 *out_syn[2];
    opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE;
+   const OpusCustomMode *mode;
+   int nbEBands;
+   int overlap;
+   const opus_int16 *eBands;
    SAVE_STACK;
 
+   mode = st->mode;
+   nbEBands = mode->nbEBands;
+   overlap = mode->overlap;
+   eBands = mode->eBands;
+
    c=0; do {
       decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap);
       out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD;
@@ -2048,15 +2067,15 @@
    } while (++c<C);
    lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
    oldBandE = lpc+C*LPC_ORDER;
-   oldLogE = oldBandE + 2*st->mode->nbEBands;
-   oldLogE2 = oldLogE + 2*st->mode->nbEBands;
-   backgroundLogE = oldLogE2  + 2*st->mode->nbEBands;
+   oldLogE = oldBandE + 2*nbEBands;
+   oldLogE2 = oldLogE + 2*nbEBands;
+   backgroundLogE = oldLogE2  + 2*nbEBands;
 
-   out_syn[0] = out_mem[0]+MAX_PERIOD-N;
-   if (C==2)
-      out_syn[1] = out_mem[1]+MAX_PERIOD-N;
+   c=0; do {
+      out_syn[c] = out_mem[c]+MAX_PERIOD-N;
+   } while (++c<C);
 
-   len = N+st->mode->overlap;
+   len = N+overlap;
 
    if (st->loss_count >= 5 || st->start!=0)
    {
@@ -2068,37 +2087,37 @@
       int effEnd;
 
       effEnd = st->end;
-      if (effEnd > st->mode->effEBands)
-         effEnd = st->mode->effEBands;
+      if (effEnd > mode->effEBands)
+         effEnd = mode->effEBands;
 
       ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
       ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */
-      ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
+      ALLOC(bandE, nbEBands*C, celt_ener);
 
       if (st->loss_count >= 5)
-         log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
+         log2Amp(mode, st->start, st->end, bandE, backgroundLogE, C);
       else {
          /* Energy decay */
          opus_val16 decay = st->loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
          c=0; do
          {
             for (i=st->start;i<st->end;i++)
-               oldBandE[c*st->mode->nbEBands+i] -= decay;
+               oldBandE[c*nbEBands+i] -= decay;
          } while (++c<C);
-         log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C);
+         log2Amp(mode, st->start, st->end, bandE, oldBandE, C);
       }
       seed = st->rng;
       for (c=0;c<C;c++)
       {
          for (i=0;i<(st->mode->eBands[st->start]<<LM);i++)
             X[c*N+i] = 0;
-         for (i=st->start;i<st->mode->effEBands;i++)
+         for (i=st->start;i<mode->effEBands;i++)
          {
             int j;
             int boffs;
             int blen;
-            boffs = N*c+(st->mode->eBands[i]<<LM);
-            blen = (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
+            boffs = N*c+(eBands[i]<<LM);
+            blen = (eBands[i+1]-eBands[i])<<LM;
             for (j=0;j<blen;j++)
             {
                seed = celt_lcg_rand(seed);
@@ -2111,22 +2130,27 @@
       }
       st->rng = seed;
 
-      denormalise_bands(st->mode, X, freq, bandE, st->mode->effEBands, C, 1<<LM);
+      denormalise_bands(mode, X, freq, bandE, mode->effEBands, C, 1<<LM);
 
       c=0; do
          for (i=0;i<st->mode->eBands[st->start]<<LM;i++)
             freq[c*N+i] = 0;
       while (++c<C);
       c=0; do {
-         int bound = st->mode->eBands[effEnd]<<LM;
+         int bound = eBands[effEnd]<<LM;
          if (st->downsample!=1)
             bound = IMIN(bound, N/st->downsample);
          for (i=bound;i<N;i++)
             freq[c*N+i] = 0;
       } while (++c<C);
-      compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
+      c=0; do {
+         OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap);
+      } while (++c<C);
+      compute_inv_mdcts(mode, 0, freq, out_syn, overlap_mem, C, LM);
    } else {
       /* Pitch-based PLC */
+      VARDECL(opus_val32, etmp);
+
       if (st->loss_count == 0)
       {
          opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1];
@@ -2144,23 +2168,26 @@
          fade = QCONST16(.8f,15);
       }
 
+      ALLOC(etmp, overlap, opus_val32);
       c=0; do {
-         VARDECL(opus_val32, e);
          opus_val16 exc[MAX_PERIOD];
          opus_val32 ac[LPC_ORDER+1];
-         opus_val16 decay = 1;
+         opus_val16 decay;
+         opus_val16 attenuation;
          opus_val32 S1=0;
          opus_val16 mem[LPC_ORDER]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+         opus_val32 *e = out_syn[c];
 
-         ALLOC(e, MAX_PERIOD+2*st->mode->overlap, opus_val32);
 
          offset = MAX_PERIOD-pitch_index;
          for (i=0;i<MAX_PERIOD;i++)
             exc[i] = ROUND16(out_mem[c][i], SIG_SHIFT);
 
+         /* Compute LPC coefficients for the last MAX_PERIOD samples before the loss so we can
+            work in the excitation-filter domain */
          if (st->loss_count == 0)
          {
-            _celt_autocorr(exc, ac, st->mode->window, st->mode->overlap,
+            _celt_autocorr(exc, ac, mode->window, overlap,
                   LPC_ORDER, MAX_PERIOD);
 
             /* Noise floor -40 dB */
@@ -2182,11 +2209,15 @@
 
             _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
          }
+         /* Samples just before the beginning of exc  */
          for (i=0;i<LPC_ORDER;i++)
-            mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
+            mem[i] = ROUND16(out_mem[c][-1-i], SIG_SHIFT);
+         /* Compute the excitation for MAX_PERIOD samples before the loss */
          celt_fir(exc, lpc+c*LPC_ORDER, exc, MAX_PERIOD, LPC_ORDER, mem);
-         /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
-         /* Check if the waveform is decaying (and if so how fast) */
+
+         /* Check if the waveform is decaying (and if so how fast)
+            We do this to avoid adding energy when concealing in a segment
+            with decaying energy */
          {
             opus_val32 E1=1, E2=1;
             int period;
@@ -2202,30 +2233,43 @@
             if (E1 > E2)
                E1 = E2;
             decay = celt_sqrt(frac_div32(SHR32(E1,1),E2));
+            attenuation = decay;
          }
 
-         /* Copy excitation, taking decay into account */
-         for (i=0;i<len+st->mode->overlap;i++)
+         /* Move memory one frame to the left */
+         OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap);
+
+         /* Extrapolate excitation with the right period, taking decay into account */
+         for (i=0;i<len;i++)
          {
             opus_val16 tmp;
             if (offset+i >= MAX_PERIOD)
             {
                offset -= pitch_index;
-               decay = MULT16_16_Q15(decay, decay);
+               attenuation = MULT16_16_Q15(attenuation, decay);
             }
-            e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
-            tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
+            e[i] = SHL32(EXTEND32(MULT16_16_Q15(attenuation, exc[offset+i])), SIG_SHIFT);
+            /* Compute the energy of the previously decoded signal whose
+               excitation we're copying */
+            tmp = ROUND16(out_mem[c][-N+offset+i],SIG_SHIFT);
             S1 += SHR32(MULT16_16(tmp,tmp),8);
          }
-         for (i=0;i<LPC_ORDER;i++)
-            mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
-         for (i=0;i<len+st->mode->overlap;i++)
-            e[i] = MULT16_32_Q15(fade, e[i]);
-         celt_iir(e, lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
 
+         /* Copy the last decoded samples (prior to the overlap region) to
+            synthesis filter memory so we can have a continuous signal. */
+         for (i=0;i<LPC_ORDER;i++)
+            mem[i] = ROUND16(out_mem[c][MAX_PERIOD-N-1-i], SIG_SHIFT);
+         /* Apply the fading if not the first loss */
+         for (i=0;i<len;i++)
+            e[i] = MULT16_32_Q15(fade, e[i]);
+         /* Synthesis filter -- back in the signal domain */
+         celt_iir(e, lpc+c*LPC_ORDER, e, len, LPC_ORDER, mem);
+
+         /* Check if the synthesis energy is higher than expected, which can
+            happen with the signal changes during our window. If so, attenuate. */
          {
             opus_val32 S2=0;
-            for (i=0;i<len+overlap;i++)
+            for (i=0;i<len;i++)
             {
                opus_val16 tmp = ROUND16(e[i],SIG_SHIFT);
                S2 += SHR32(MULT16_16(tmp,tmp),8);
@@ -2234,51 +2278,45 @@
 #ifdef FIXED_POINT
             if (!(S1 > SHR32(S2,2)))
 #else
-               /* Float test is written this way to catch NaNs at the same time */
-               if (!(S1 > 0.2f*S2))
+            /* Float test is written this way to catch NaNs at the same time */
+            if (!(S1 > 0.2f*S2))
 #endif
+            {
+               for (i=0;i<len;i++)
+                  e[i] = 0;
+            } else if (S1 < S2)
+            {
+               opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
+               for (i=0;i<overlap;i++)
                {
-                  for (i=0;i<len+overlap;i++)
-                     e[i] = 0;
-               } else if (S1 < S2)
-               {
-                  opus_val16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
-                  for (i=0;i<len+overlap;i++)
-                     e[i] = MULT16_32_Q15(ratio, e[i]);
+                  opus_val16 tmp_g = Q15ONE - MULT16_16_Q15(mode->window[i], Q15ONE-ratio);
+                  e[i] = MULT16_32_Q15(tmp_g, e[i]);
                }
+               for (i=overlap;i<len;i++)
+                  e[i] = MULT16_32_Q15(ratio, e[i]);
+            }
          }
 
-         /* Apply post-filter to the MDCT overlap of the previous frame */
-         comb_filter(out_mem[c]+MAX_PERIOD, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
-               st->postfilter_gain, st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
+         /* Apply pre-filter to the MDCT overlap for the next frame because the
+            post-filter will be re-applied in the decoder after the MDCT overlap */
+         comb_filter(etmp, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
+               -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
                NULL, 0);
 
-         for (i=0;i<MAX_PERIOD+st->mode->overlap-N;i++)
-            out_mem[c][i] = out_mem[c][N+i];
-
-         /* Apply TDAC to the concealed audio so that it blends with the
-         previous and next frames */
+         /* Simulate TDAC on the concealed audio so that it blends with the
+            MDCT of next frames. */
          for (i=0;i<overlap/2;i++)
          {
             opus_val32 tmp;
-            tmp = MULT16_32_Q15(st->mode->window[i],           e[N+overlap-1-i]) +
-                  MULT16_32_Q15(st->mode->window[overlap-i-1], e[N+i          ]);
-            out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(st->mode->window[overlap-i-1], tmp);
-            out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(st->mode->window[i], tmp);
+            tmp = MULT16_32_Q15(mode->window[i],           etmp[overlap-1-i]) +
+                  MULT16_32_Q15(mode->window[overlap-i-1], etmp[i          ]);
+            out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(mode->window[overlap-i-1], tmp);
+            out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(mode->window[i], tmp);
          }
-         for (i=0;i<N;i++)
-            out_mem[c][MAX_PERIOD-N+i] = e[i];
-
-         /* Apply pre-filter to the MDCT overlap for the next frame (post-filter will be applied then) */
-         comb_filter(e, out_mem[c]+MAX_PERIOD, st->postfilter_period, st->postfilter_period, st->overlap,
-               -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset,
-               NULL, 0);
-         for (i=0;i<overlap;i++)
-            out_mem[c][MAX_PERIOD+i] = e[i];
       } while (++c<C);
    }
 
-   deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD);
+   deemphasis(out_syn, pcm, N, C, st->downsample, mode->preemph, st->preemph_memD);
 
    st->loss_count++;
 
@@ -2387,6 +2425,13 @@
    if (effEnd > st->mode->effEBands)
       effEnd = st->mode->effEBands;
 
+   if (data == NULL || len<=1)
+   {
+      celt_decode_lost(st, pcm, N, LM);
+      RESTORE_STACK;
+      return frame_size/st->downsample;
+   }
+
    ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */
    ALLOC(X, C*N, celt_norm);   /**< Interleaved normalised MDCTs */
    ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
@@ -2399,13 +2444,6 @@
          X[c*N+i] = 0;
    while (++c<C);
 
-   if (data == NULL || len<=1)
-   {
-      celt_decode_lost(st, pcm, N, LM);
-      RESTORE_STACK;
-      return frame_size/st->downsample;
-   }
-
    if (dec == NULL)
    {
       ec_dec_init(&_dec,(unsigned char*)data,len);
@@ -2800,7 +2838,6 @@
          *value = st->postfilter_period;
       }
       break;
-#ifdef OPUS_BUILD
       case CELT_GET_MODE_REQUEST:
       {
          const CELTMode ** value = va_arg(ap, const CELTMode**);
@@ -2823,7 +2860,6 @@
          *value=st->rng;
       }
       break;
-#endif
       default:
          goto bad_request;
    }
diff --git a/celt/cwrs.c b/celt/cwrs.c
index ac81a7e..8edc919 100644
--- a/celt/cwrs.c
+++ b/celt/cwrs.c
@@ -337,7 +337,7 @@
     but _k isn't tested here because k<=52 for n=7*/
   if(_n<=6)
 #endif
- {
+  {
     /*If _n==0, _u[0] should be 1 and the rest should be 0.*/
     /*If _n==1, _u[i] should be 1 for i>1.*/
     celt_assert(_n>=2);
diff --git a/celt/ecintrin.h b/celt/ecintrin.h
index 3dffa5f..be57dd4 100644
--- a/celt/ecintrin.h
+++ b/celt/ecintrin.h
@@ -48,7 +48,7 @@
 /*Count leading zeros.
   This macro should only be used for implementing ec_ilog(), if it is defined.
   All other code should use EC_ILOG() instead.*/
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
 # include <intrin.h>
 /*In _DEBUG mode this is not an intrinsic by default.*/
 # pragma intrinsic(_BitScanReverse)
diff --git a/celt/entcode.c b/celt/entcode.c
index 02ac690..fa5d7c7 100644
--- a/celt/entcode.c
+++ b/celt/entcode.c
@@ -33,6 +33,11 @@
 #include "arch.h"
 
 #if !defined(EC_CLZ)
+/*This is a fallback for systems where we don't know how to access
+   a BSR or CLZ instruction (see ecintrin.h).
+  If you are optimizing Opus on a new platform and it has a native CLZ or
+   BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be
+   an easy performance win.*/
 int ec_ilog(opus_uint32 _v){
   /*On a Pentium M, this branchless version tested as the fastest on
      1,000,000,000 random 32-bit integers, edging out a similar version with
diff --git a/celt/pitch.c b/celt/pitch.c
index c2f08ec..ca0f523 100644
--- a/celt/pitch.c
+++ b/celt/pitch.c
@@ -77,7 +77,7 @@
 #ifndef FIXED_POINT
          /* Considering the range of xcorr16, this should avoid both underflows
             and overflows (inf) when squaring xcorr16 */
-         xcorr16 *= 1e-12;
+         xcorr16 *= 1e-12f;
 #endif
          num = MULT16_16_Q15(xcorr16,xcorr16);
          if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy))
diff --git a/celt/quant_bands.c b/celt/quant_bands.c
index b1d4eb1..66f1f5f 100644
--- a/celt/quant_bands.c
+++ b/celt/quant_bands.c
@@ -283,12 +283,15 @@
    /* Encode the global flags using a simple probability model
       (first symbols in the stream) */
 
+   max_decay = QCONST16(16.f,DB_SHIFT);
+   if (end-start>10)
+   {
 #ifdef FIXED_POINT
-      max_decay = MIN32(QCONST16(16.f,DB_SHIFT), SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
+      max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3));
 #else
-   max_decay = MIN32(16.f, .125f*nbAvailableBytes);
+      max_decay = MIN32(max_decay, .125f*nbAvailableBytes);
 #endif
-
+   }
    enc_start_state = *enc;
 
    ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
diff --git a/celt/rate.c b/celt/rate.c
index 32fe9ac..4e96787 100644
--- a/celt/rate.c
+++ b/celt/rate.c
@@ -84,7 +84,7 @@
    unsigned char *bits;
    unsigned char *cap;
 
-   cindex = opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
+   cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
    cache->index = cindex;
 
    /* Scan for all unique band sizes */
@@ -124,7 +124,7 @@
          }
       }
    }
-   bits = opus_alloc(sizeof(unsigned char)*curr);
+   bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr);
    cache->bits = bits;
    cache->size = curr;
    /* Compute the cache for all unique sizes */
@@ -140,7 +140,7 @@
 
    /* Compute the maximum rate for each band at which we'll reliably use as
        many bits as we ask for. */
-   cache->caps = cap = opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);
+   cache->caps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);
    for (i=0;i<=LM;i++)
    {
       for (C=1;C<=2;C++)
@@ -259,7 +259,7 @@
    int alloc_floor;
    opus_int32 left, percoeff;
    int done;
-   int balance;
+   opus_int32 balance;
    SAVE_STACK;
 
    alloc_floor = C<<BITRES;
@@ -353,7 +353,7 @@
 #ifdef FUZZING
             if ((rand()&0x1) == 0)
 #else
-            if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
+            if (codedBands<=start+2 || band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
 #endif
             {
                ec_enc_bit_logp(ec, 1, 1);
@@ -432,17 +432,17 @@
       int N0, N, den;
       int offset;
       int NClogN;
-      int excess;
+      opus_int32 excess, bit;
 
       celt_assert(bits[j] >= 0);
       N0 = m->eBands[j+1]-m->eBands[j];
       N=N0<<LM;
-      bits[j] += balance;
+      bit = (opus_int32)bits[j]+balance;
 
       if (N>1)
       {
-         excess = IMAX(bits[j]-cap[j],0);
-         bits[j] -= excess;
+         excess = MAX32(bit-cap[j],0);
+         bits[j] = bit-excess;
 
          /* Compensate for the extra DoF in stereo */
          den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0));
@@ -483,8 +483,8 @@
 
       } else {
          /* For N=1, all bits go to fine energy except for a single sign bit */
-         excess = IMAX(0,bits[j]-(C<<BITRES));
-         bits[j] -= excess;
+         excess = MAX32(0,bit-(C<<BITRES));
+         bits[j] = bit-excess;
          ebits[j] = 0;
          fine_priority[j] = 1;
       }
diff --git a/celt/tests/test_unit_cwrs32.c b/celt/tests/test_unit_cwrs32.c
index 905714e..4695f2d 100644
--- a/celt/tests/test_unit_cwrs32.c
+++ b/celt/tests/test_unit_cwrs32.c
@@ -1,3 +1,31 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
+                           Gregory Maxwell
+   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_dft.c b/celt/tests/test_unit_dft.c
index 5ca38ed..7ff0be0 100644
--- a/celt/tests/test_unit_dft.c
+++ b/celt/tests/test_unit_dft.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008 Xiph.Org Foundation
+   Written by Jean-Marc Valin */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_entropy.c b/celt/tests/test_unit_entropy.c
index 5cba4fe..bd83986 100644
--- a/celt/tests/test_unit_entropy.c
+++ b/celt/tests/test_unit_entropy.c
@@ -1,3 +1,31 @@
+/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,
+                           Gregory Maxwell
+   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_laplace.c b/celt/tests/test_unit_laplace.c
index 5c80c19..b0f5935 100644
--- a/celt/tests/test_unit_laplace.c
+++ b/celt/tests/test_unit_laplace.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation
+   Written by Jean-Marc Valin and Timothy B. Terriberry */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_mathops.c b/celt/tests/test_unit_mathops.c
index ea0af49..c11f0ad 100644
--- a/celt/tests/test_unit_mathops.c
+++ b/celt/tests/test_unit_mathops.c
@@ -1,3 +1,31 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
+                           Gregory Maxwell
+   Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_mdct.c b/celt/tests/test_unit_mdct.c
index 0de3d54..f8fb9ac 100644
--- a/celt/tests/test_unit_mdct.c
+++ b/celt/tests/test_unit_mdct.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation
+   Written by Jean-Marc Valin */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_rotation.c b/celt/tests/test_unit_rotation.c
index 29082b6..ce5f096 100644
--- a/celt/tests/test_unit_rotation.c
+++ b/celt/tests/test_unit_rotation.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation
+   Written by Jean-Marc Valin */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt/tests/test_unit_types.c b/celt/tests/test_unit_types.c
index 1c3357e..67a0fb8 100644
--- a/celt/tests/test_unit_types.c
+++ b/celt/tests/test_unit_types.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation
+   Written by Jean-Marc Valin */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
diff --git a/celt_headers.mk b/celt_headers.mk
new file mode 100644
index 0000000..f89d66a
--- /dev/null
+++ b/celt_headers.mk
@@ -0,0 +1,31 @@
+CELT_HEAD = \
+celt/arch.h \
+celt/bands.h \
+celt/celt.h \
+include/opus_types.h \
+include/opus_defines.h \
+include/opus_custom.h \
+celt/cwrs.h \
+celt/ecintrin.h \
+celt/entcode.h \
+celt/entdec.h \
+celt/entenc.h \
+celt/fixed_debug.h \
+celt/fixed_generic.h \
+celt/float_cast.h \
+celt/_kiss_fft_guts.h \
+celt/kiss_fft.h \
+celt/laplace.h \
+celt/mathops.h \
+celt/mdct.h \
+celt/mfrngcod.h \
+celt/modes.h \
+celt/os_support.h \
+celt/pitch.h \
+celt/celt_lpc.h \
+celt/quant_bands.h \
+celt/rate.h \
+celt/stack_alloc.h \
+celt/vq.h \
+celt/static_modes_float.h \
+celt/static_modes_fixed.h
diff --git a/celt_sources.mk b/celt_sources.mk
new file mode 100644
index 0000000..6f0a90e
--- /dev/null
+++ b/celt_sources.mk
@@ -0,0 +1,16 @@
+CELT_SOURCES = celt/bands.c \
+celt/celt.c \
+celt/cwrs.c \
+celt/entcode.c \
+celt/entdec.c \
+celt/entenc.c \
+celt/kiss_fft.c \
+celt/laplace.c \
+celt/mathops.c \
+celt/mdct.c \
+celt/modes.c \
+celt/pitch.c \
+celt/celt_lpc.c \
+celt/quant_bands.c \
+celt/rate.c \
+celt/vq.c
diff --git a/compile b/compile
index b1f4749..862a14e 100755
--- a/compile
+++ b/compile
@@ -1,7 +1,7 @@
 #! /bin/sh
 # Wrapper for compilers which do not understand '-c -o'.
 
-scriptversion=2012-01-04.17; # UTC
+scriptversion=2012-03-05.13; # UTC
 
 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free
 # Software Foundation, Inc.
@@ -79,6 +79,48 @@
   esac
 }
 
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
 # func_cl_wrapper cl arg...
 # Adjust compile command to suit cl
 func_cl_wrapper ()
@@ -109,43 +151,34 @@
 	      ;;
 	  esac
 	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
 	-I*)
 	  func_file_conv "${1#-I}" mingw
 	  set x "$@" -I"$file"
 	  shift
 	  ;;
-	-l*)
-	  lib=${1#-l}
-	  found=no
-	  save_IFS=$IFS
-	  IFS=';'
-	  for dir in $lib_path $LIB
-	  do
-	    IFS=$save_IFS
-	    if $shared && test -f "$dir/$lib.dll.lib"; then
-	      found=yes
-	      set x "$@" "$dir/$lib.dll.lib"
-	      break
-	    fi
-	    if test -f "$dir/$lib.lib"; then
-	      found=yes
-	      set x "$@" "$dir/$lib.lib"
-	      break
-	    fi
-	  done
-	  IFS=$save_IFS
-
-	  test "$found" != yes && set x "$@" "$lib.lib"
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
 	  shift
 	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
 	-L*)
-	  func_file_conv "${1#-L}"
-	  if test -z "$lib_path"; then
-	    lib_path=$file
-	  else
-	    lib_path="$lib_path;$file"
-	  fi
-	  linker_opts="$linker_opts -LIBPATH:$file"
+	  func_cl_dashL "${1#-L}"
 	  ;;
 	-static)
 	  shared=false
diff --git a/config.guess b/config.guess
index 49ba16f..d622a44 100755
--- a/config.guess
+++ b/config.guess
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #   2011, 2012 Free Software Foundation, Inc.
 
-timestamp='2012-01-01'
+timestamp='2012-02-10'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -17,9 +17,7 @@
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -863,6 +861,13 @@
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
 	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
     alpha:Linux:*:*)
 	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
 	  EV5)   UNAME_MACHINE=alphaev5 ;;
@@ -1320,6 +1325,9 @@
     i*86:AROS:*:*)
 	echo ${UNAME_MACHINE}-pc-aros
 	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
diff --git a/config.h.in b/config.h.in
index bf3b61a..a5e9503 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,8 +1,5 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
-/* Define if building universal (internal helper macro) */
-#undef AC_APPLE_UNIVERSAL_BUILD
-
 /* Custom modes */
 #undef CUSTOM_MODES
 
@@ -15,9 +12,6 @@
 /* Compile as fixed-point (for machines without a fast enough FPU) */
 #undef FIXED_POINT
 
-/* Compile as floating-point (for machines with a fast enough FPU) */
-#undef FLOATING_POINT
-
 /* Float approximations */
 #undef FLOAT_APPROX
 
@@ -121,18 +115,6 @@
 /* Use C99 variable-size arrays */
 #undef VAR_ARRAYS
 
-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
-   significant byte first (like Motorola and SPARC, unlike Intel). */
-#if defined AC_APPLE_UNIVERSAL_BUILD
-# if defined __BIG_ENDIAN__
-#  define WORDS_BIGENDIAN 1
-# endif
-#else
-# ifndef WORDS_BIGENDIAN
-#  undef WORDS_BIGENDIAN
-# endif
-#endif
-
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
diff --git a/config.sub b/config.sub
index d6b6b3c..c894da4 100755
--- a/config.sub
+++ b/config.sub
@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #   2011, 2012 Free Software Foundation, Inc.
 
-timestamp='2012-01-01'
+timestamp='2012-02-10'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -21,9 +21,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -132,6 +130,10 @@
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
   *)
     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
     if [ $basic_machine != $1 ]
@@ -247,6 +249,7 @@
 	# Some are omitted here because they have special meanings below.
 	1750a | 580 \
 	| a29k \
+	| aarch64 | aarch64_be \
 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
 	| am33_2.0 \
@@ -319,7 +322,7 @@
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -332,7 +335,10 @@
 	strongarm | thumb | xscale)
 		basic_machine=arm-unknown
 		;;
-
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
 	xscaleeb)
 		basic_machine=armeb-unknown
 		;;
@@ -355,6 +361,7 @@
 	# Recognize the basic CPU types with company name.
 	580-* \
 	| a29k-* \
+	| aarch64-* | aarch64_be-* \
 	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
diff --git a/configure b/configure
index bcb9c7a..00405ba 100755
--- a/configure
+++ b/configure
@@ -613,6 +613,8 @@
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+PC_LIBM
+PC_BUILD
 CUSTOM_MODES_FALSE
 CUSTOM_MODES_TRUE
 FIXED_POINT_FALSE
@@ -1393,7 +1395,7 @@
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-silent-rules          less verbose build output (undo: `make V=1')
   --disable-silent-rules         verbose build output (undo: `make V=0')
-  --enable-maintainer-mode  enable make rules and dependencies not useful
+  --disable-maintainer-mode  disable make rules and dependencies not useful
 			  (and sometimes confusing) to the casual installer
   --enable-shared[=PKGS]  build shared libraries [default=yes]
   --enable-static[=PKGS]  build static libraries [default=yes]
@@ -2484,9 +2486,9 @@
 
 
 # For libtool.
-OPUS_LT_CURRENT=2
+OPUS_LT_CURRENT=3
 OPUS_LT_REVISION=0
-OPUS_LT_AGE=2
+OPUS_LT_AGE=3
 
 
 
@@ -2997,7 +2999,7 @@
 if test "${enable_maintainer_mode+set}" = set; then :
   enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
 else
-  USE_MAINTAINER_MODE=no
+  USE_MAINTAINER_MODE=yes
 fi
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
@@ -11887,230 +11889,6 @@
 fi
 
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
-$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if ${ac_cv_c_bigendian+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_c_bigendian=unknown
-    # See if we're dealing with a universal compiler.
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifndef __APPLE_CC__
-	       not a universal capable compiler
-	     #endif
-	     typedef int dummy;
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-	# Check for potential -arch flags.  It is not universal unless
-	# there are at least two -arch flags with different values.
-	ac_arch=
-	ac_prev=
-	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
-	 if test -n "$ac_prev"; then
-	   case $ac_word in
-	     i?86 | x86_64 | ppc | ppc64)
-	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
-		 ac_arch=$ac_word
-	       else
-		 ac_cv_c_bigendian=universal
-		 break
-	       fi
-	       ;;
-	   esac
-	   ac_prev=
-	 elif test "x$ac_word" = "x-arch"; then
-	   ac_prev=arch
-	 fi
-       done
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    if test $ac_cv_c_bigendian = unknown; then
-      # See if sys/param.h defines the BYTE_ORDER macro.
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-	     #include <sys/param.h>
-
-int
-main ()
-{
-#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
-		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
-		     && LITTLE_ENDIAN)
-	      bogus endian macros
-	     #endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  # It does; now see whether it defined to BIG_ENDIAN or not.
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-		#include <sys/param.h>
-
-int
-main ()
-{
-#if BYTE_ORDER != BIG_ENDIAN
-		 not big endian
-		#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_c_bigendian=yes
-else
-  ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-    if test $ac_cv_c_bigendian = unknown; then
-      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
-      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <limits.h>
-
-int
-main ()
-{
-#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
-	      bogus endian macros
-	     #endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  # It does; now see whether it defined to _BIG_ENDIAN or not.
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <limits.h>
-
-int
-main ()
-{
-#ifndef _BIG_ENDIAN
-		 not big endian
-		#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_c_bigendian=yes
-else
-  ac_cv_c_bigendian=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-    if test $ac_cv_c_bigendian = unknown; then
-      # Compile a test program.
-      if test "$cross_compiling" = yes; then :
-  # Try to guess by grepping values from an object file.
-	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-short int ascii_mm[] =
-		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-		short int ascii_ii[] =
-		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-		int use_ascii (int i) {
-		  return ascii_mm[i] + ascii_ii[i];
-		}
-		short int ebcdic_ii[] =
-		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-		short int ebcdic_mm[] =
-		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-		int use_ebcdic (int i) {
-		  return ebcdic_mm[i] + ebcdic_ii[i];
-		}
-		extern int foo;
-
-int
-main ()
-{
-return use_ascii (foo) == use_ebcdic (foo);
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
-	      ac_cv_c_bigendian=yes
-	    fi
-	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
-	      if test "$ac_cv_c_bigendian" = unknown; then
-		ac_cv_c_bigendian=no
-	      else
-		# finding both strings is unlikely to happen, but who knows?
-		ac_cv_c_bigendian=unknown
-	      fi
-	    fi
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$ac_includes_default
-int
-main ()
-{
-
-	     /* Are we little or big endian?  From Harbison&Steele.  */
-	     union
-	     {
-	       long int l;
-	       char c[sizeof (long int)];
-	     } u;
-	     u.l = 1;
-	     return u.c[sizeof (long int) - 1] == 1;
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  ac_cv_c_bigendian=no
-else
-  ac_cv_c_bigendian=yes
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-    fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
-$as_echo "$ac_cv_c_bigendian" >&6; }
- case $ac_cv_c_bigendian in #(
-   yes)
-     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
-;; #(
-   no)
-      ;; #(
-   universal)
-
-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
-
-     ;; #(
-   *)
-     as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
- esac
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
 if ${ac_cv_c_const+:} false; then :
@@ -12428,15 +12206,7 @@
 
 $as_echo "#define FIXED_POINT 1" >>confdefs.h
 
-else
-
-$as_echo "#define FLOATING_POINT /**/" >>confdefs.h
-
 fi
-else
-
-$as_echo "#define FLOATING_POINT /**/" >>confdefs.h
-
 fi
 
 
@@ -12820,8 +12590,24 @@
 fi
 
 
+if test x$ac_enable_float = xyes; then
+  PC_BUILD="floating-point"
+  PC_LIBM=$LIBM
+else
+  PC_BUILD="fixed-point"
+  PC_LIBM=
+fi
+if test x$ac_enable_custom_modes = xyes; then
+  PC_BUILD="${PC_BUILD}, custom modes"
+  PC_LIBM=$LIBM
+fi
+
+
+
+
 ac_config_files="$ac_config_files Makefile opus.pc opus-uninstalled.pc doc/Makefile doc/Doxyfile"
 
+
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -12951,7 +12737,6 @@
   as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-
 if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/configure.ac b/configure.ac
index 0773c37..6394e2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,16 +53,16 @@
 
 # For libtool.
 dnl Please update these for releases.
-OPUS_LT_CURRENT=2
+OPUS_LT_CURRENT=3
 OPUS_LT_REVISION=0
-OPUS_LT_AGE=2
+OPUS_LT_AGE=3
 
 AC_SUBST(OPUS_LT_CURRENT)
 AC_SUBST(OPUS_LT_REVISION)
 AC_SUBST(OPUS_LT_AGE)
 
 AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
-AM_MAINTAINER_MODE
+AM_MAINTAINER_MODE([enable])
 
 AC_CANONICAL_HOST
 AC_MINGW32
@@ -70,7 +70,6 @@
 AM_PROG_CC_C_O
 
 AC_PROG_CC_C99
-AC_C_BIGENDIAN
 AC_C_CONST
 AC_C_INLINE
 
@@ -159,10 +158,7 @@
   ac_enable_fixed="yes";
   ac_enable_float="no";
   AC_DEFINE([FIXED_POINT], [1], [Compile as fixed-point (for machines without a fast enough FPU)])
-else
-  AC_DEFINE([FLOATING_POINT], , [Compile as floating-point (for machines with a fast enough FPU)])
-fi],
-AC_DEFINE([FLOATING_POINT], , [Compile as floating-point (for machines with a fast enough FPU)]))
+fi])
 
 ac_enable_fixed_debug="no"
 AC_ARG_ENABLE(fixed-point-debug, [  --enable-fixed-point-debug debug fixed-point implementation],
@@ -278,8 +274,27 @@
 AM_CONDITIONAL([FIXED_POINT], [test x$ac_enable_fixed = xyes])
 AM_CONDITIONAL([CUSTOM_MODES], [test x$ac_enable_custom_modes = xyes])
 
-AC_OUTPUT([Makefile opus.pc opus-uninstalled.pc
-           doc/Makefile doc/Doxyfile])
+dnl subsitutions for the pkg-config files
+if test x$ac_enable_float = xyes; then
+  PC_BUILD="floating-point"
+  PC_LIBM=$LIBM
+else
+  PC_BUILD="fixed-point"
+  PC_LIBM=
+fi
+dnl opus_custom requires libm as well
+if test x$ac_enable_custom_modes = xyes; then
+  PC_BUILD="${PC_BUILD}, custom modes"
+  PC_LIBM=$LIBM
+fi
+AC_SUBST([PC_BUILD])
+AC_SUBST([PC_LIBM])
+
+
+AC_CONFIG_FILES([Makefile opus.pc opus-uninstalled.pc
+                 doc/Makefile doc/Doxyfile])
+
+AC_OUTPUT
 
 AC_MSG_RESULT([
 ------------------------------------------------------------------------
diff --git a/depcomp b/depcomp
index bd0ac08..25a39e6 100755
--- a/depcomp
+++ b/depcomp
@@ -1,10 +1,10 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2011-12-04.11; # UTC
+scriptversion=2012-03-27.16; # UTC
 
 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010,
-# 2011 Free Software Foundation, Inc.
+# 2011, 2012 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
 
 case $1 in
   '')
-     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
      exit 1;
      ;;
   -h | --h*)
@@ -40,8 +40,8 @@
 
 Environment variables:
   depmode     Dependency tracking mode.
-  source      Source file read by `PROGRAMS ARGS'.
-  object      Object file output by `PROGRAMS ARGS'.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
   DEPDIR      directory where to store dependencies.
   depfile     Dependency file to output.
   tmpdepfile  Temporary file to use when outputting dependencies.
@@ -57,6 +57,12 @@
     ;;
 esac
 
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+
 if test -z "$depmode" || test -z "$source" || test -z "$object"; then
   echo "depcomp: Variables source, object and depmode must be set" 1>&2
   exit 1
@@ -102,6 +108,12 @@
    depmode=msvc7
 fi
 
+if test "$depmode" = xlc; then
+   # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
+   gccflag=-qmakedep=gcc,-MF
+   depmode=gcc
+fi
+
 case "$depmode" in
 gcc3)
 ## gcc 3 implements dependency tracking that does exactly what
@@ -156,15 +168,14 @@
 ## The second -e expression handles DOS-style file names with drive letters.
   sed -e 's/^[^:]*: / /' \
       -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
-## This next piece of magic avoids the `deleted header file' problem.
+## This next piece of magic avoids the "deleted header file" problem.
 ## The problem is that when a header file which appears in a .P file
 ## is deleted, the dependency causes make to die (because there is
 ## typically no way to rebuild the header).  We avoid this by adding
 ## dummy dependencies for each header file.  Too bad gcc doesn't do
 ## this for us directly.
-  tr ' ' '
-' < "$tmpdepfile" |
-## Some versions of gcc put a space before the `:'.  On the theory
+  tr ' ' "$nl" < "$tmpdepfile" |
+## Some versions of gcc put a space before the ':'.  On the theory
 ## that the space means something, we add a space to the output as
 ## well.  hp depmode also adds that space, but also prefixes the VPATH
 ## to the object.  Take care to not repeat it in the output.
@@ -203,18 +214,15 @@
     # clever and replace this with sed code, as IRIX sed won't handle
     # lines with more than a fixed number of characters (4096 in
     # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
-    # the IRIX cc adds comments like `#:fec' to the end of the
+    # the IRIX cc adds comments like '#:fec' to the end of the
     # dependency line.
-    tr ' ' '
-' < "$tmpdepfile" \
+    tr ' ' "$nl" < "$tmpdepfile" \
     | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
-    tr '
-' ' ' >> "$depfile"
+    tr "$nl" ' ' >> "$depfile"
     echo >> "$depfile"
 
     # The second pass generates a dummy entry for each header file.
-    tr ' ' '
-' < "$tmpdepfile" \
+    tr ' ' "$nl" < "$tmpdepfile" \
    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
    >> "$depfile"
   else
@@ -226,10 +234,17 @@
   rm -f "$tmpdepfile"
   ;;
 
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
 aix)
   # The C for AIX Compiler uses -M and outputs the dependencies
   # in a .u file.  In older versions, this file always lives in the
-  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
   # start of each line; $object doesn't have directory information.
   # Version 6 uses the directory in both cases.
   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
@@ -259,12 +274,11 @@
     test -f "$tmpdepfile" && break
   done
   if test -f "$tmpdepfile"; then
-    # Each line is of the form `foo.o: dependent.h'.
+    # Each line is of the form 'foo.o: dependent.h'.
     # Do two passes, one to just change these to
-    # `$object: dependent.h' and one to simply `dependent.h:'.
+    # '$object: dependent.h' and one to simply 'dependent.h:'.
     sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
-    # That's a tab and a space in the [].
-    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+    sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
   else
     # The sourcefile does not contain any dependencies, so just
     # store a dummy comment line, to avoid errors with the Makefile
@@ -275,23 +289,26 @@
   ;;
 
 icc)
-  # Intel's C compiler understands `-MD -MF file'.  However on
-  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
+  # However on
+  #    $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c
   # ICC 7.0 will fill foo.d with something like
   #    foo.o: sub/foo.c
   #    foo.o: sub/foo.h
-  # which is wrong.  We want:
+  # which is wrong.  We want
   #    sub/foo.o: sub/foo.c
   #    sub/foo.o: sub/foo.h
   #    sub/foo.c:
   #    sub/foo.h:
   # ICC 7.1 will output
   #    foo.o: sub/foo.c sub/foo.h
-  # and will wrap long lines using \ :
+  # and will wrap long lines using '\':
   #    foo.o: sub/foo.c ... \
   #     sub/foo.h ... \
   #     ...
-
+  # tcc 0.9.26 (FIXME still under development at the moment of writing)
+  # will emit a similar output, but also prepend the continuation lines
+  # with horizontal tabulation characters.
   "$@" -MD -MF "$tmpdepfile"
   stat=$?
   if test $stat -eq 0; then :
@@ -300,15 +317,21 @@
     exit $stat
   fi
   rm -f "$depfile"
-  # Each line is of the form `foo.o: dependent.h',
-  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Each line is of the form 'foo.o: dependent.h',
+  # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'.
   # Do two passes, one to just change these to
-  # `$object: dependent.h' and one to simply `dependent.h:'.
-  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
-  # Some versions of the HPUX 10.20 sed can't process this invocation
-  # correctly.  Breaking it into two sed invocations is a workaround.
-  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
-    sed -e 's/$/ :/' >> "$depfile"
+  # '$object: dependent.h' and one to simply 'dependent.h:'.
+  sed -e "s/^[ $tab][ $tab]*/  /" -e "s,^[^:]*:,$object :," \
+    < "$tmpdepfile" > "$depfile"
+  sed '
+    s/[ '"$tab"'][ '"$tab"']*/ /g
+    s/^ *//
+    s/ *\\*$//
+    s/^[^:]*: *//
+    /^$/d
+    /:$/d
+    s/$/ :/
+  ' < "$tmpdepfile" >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
@@ -344,7 +367,7 @@
   done
   if test -f "$tmpdepfile"; then
     sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
-    # Add `dependent.h:' lines.
+    # Add 'dependent.h:' lines.
     sed -ne '2,${
 	       s/^ *//
 	       s/ \\*$//
@@ -359,9 +382,9 @@
 
 tru64)
    # The Tru64 compiler uses -MD to generate dependencies as a side
-   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
    # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
-   # dependencies in `foo.d' instead, so we check for that too.
+   # dependencies in 'foo.d' instead, so we check for that too.
    # Subdirectories are respected.
    dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
    test "x$dir" = "x$object" && dir=
@@ -407,8 +430,7 @@
    done
    if test -f "$tmpdepfile"; then
       sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
-      # That's a tab and a space in the [].
-      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+      sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
    else
       echo "#dummy" > "$depfile"
    fi
@@ -443,11 +465,11 @@
   p
 }' | $cygpath_u | sort -u | sed -n '
 s/ /\\ /g
-s/\(.*\)/	\1 \\/p
+s/\(.*\)/'"$tab"'\1 \\/p
 s/.\(.*\) \\/\1:/
 H
 $ {
-  s/.*/	/
+  s/.*/'"$tab"'/
   G
   p
 }' >> "$depfile"
@@ -478,7 +500,7 @@
     shift
   fi
 
-  # Remove `-o $object'.
+  # Remove '-o $object'.
   IFS=" "
   for arg
   do
@@ -498,15 +520,14 @@
   done
 
   test -z "$dashmflag" && dashmflag=-M
-  # Require at least two characters before searching for `:'
+  # Require at least two characters before searching for ':'
   # in the target name.  This is to cope with DOS-style filenames:
-  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
   "$@" $dashmflag |
-    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+    sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
   rm -f "$depfile"
   cat < "$tmpdepfile" > "$depfile"
-  tr ' ' '
-' < "$tmpdepfile" | \
+  tr ' ' "$nl" < "$tmpdepfile" | \
 ## Some versions of the HPUX 10.20 sed can't process this invocation
 ## correctly.  Breaking it into two sed invocations is a workaround.
     sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
@@ -562,8 +583,7 @@
   # makedepend may prepend the VPATH from the source file name to the object.
   # No need to regex-escape $object, excess matching of '.' is harmless.
   sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
-  sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
+  sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
 ## Some versions of the HPUX 10.20 sed can't process this invocation
 ## correctly.  Breaking it into two sed invocations is a workaround.
     sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
@@ -583,7 +603,7 @@
     shift
   fi
 
-  # Remove `-o $object'.
+  # Remove '-o $object'.
   IFS=" "
   for arg
   do
@@ -652,8 +672,8 @@
   sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
   rm -f "$depfile"
   echo "$object : \\" > "$depfile"
-  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
-  echo "	" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
   sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 328a06e..7f5f7dc 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -835,7 +835,7 @@
 # standard header. Note that when using a custom header you are responsible
 # for the proper inclusion of any scripts and style sheets that doxygen
 # needs, which is dependent on the configuration options used.
-# It is adviced to generate a default header using "doxygen -w html
+# It is advised to generate a default header using "doxygen -w html
 # header.html footer.html stylesheet.css YourConfigFile" and then modify
 # that header. Note that the header is subject to change so you typically
 # have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW!
diff --git a/doc/Makefile.am b/doc/Makefile.am
index ba6f64c..cf5908a 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -22,7 +22,8 @@
 
 install-data-local:
 	for f in `find html -type f \! -name "installdox"`; do	\
-		$(INSTALL_DATA) -D $$f $(DESTDIR)$(docdir)/$$f;	\
+		$(INSTALL) -d $(DESTDIR)$(docdir)/html/search;	\
+		$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f;	\
 	done
 
 	$(INSTALL) -d $(DESTDIR)$(mandir)/man3
diff --git a/doc/Makefile.in b/doc/Makefile.in
index a40d72c..1eb4436 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -15,6 +15,23 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
+am__make_dryrun = \
+  { \
+    am__dry=no; \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        echo 'am--echo: ; @echo "AM"  OK' | $(MAKE) -f - 2>/dev/null \
+          | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+      *) \
+        for am__flg in $$MAKEFLAGS; do \
+          case $$am__flg in \
+            *=*|--*) ;; \
+            *n*) am__dry=yes; break;; \
+          esac; \
+        done;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -52,6 +69,11 @@
 am__v_at_0 = @
 SOURCES =
 DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -116,6 +138,8 @@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PC_BUILD = @PC_BUILD@
+PC_LIBM = @PC_LIBM@
 RANLIB = @RANLIB@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
@@ -393,7 +417,8 @@
 
 @HAVE_DOXYGEN_TRUE@install-data-local:
 @HAVE_DOXYGEN_TRUE@	for f in `find html -type f \! -name "installdox"`; do	\
-@HAVE_DOXYGEN_TRUE@		$(INSTALL_DATA) -D $$f $(DESTDIR)$(docdir)/$$f;	\
+@HAVE_DOXYGEN_TRUE@		$(INSTALL) -d $(DESTDIR)$(docdir)/html/search;	\
+@HAVE_DOXYGEN_TRUE@		$(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f;	\
 @HAVE_DOXYGEN_TRUE@	done
 
 @HAVE_DOXYGEN_TRUE@	$(INSTALL) -d $(DESTDIR)$(mandir)/man3
diff --git a/include/opus.h b/include/opus.h
index a1f0156..847a07c 100644
--- a/include/opus.h
+++ b/include/opus.h
@@ -67,6 +67,7 @@
  * @li @ref opus_encoder
  * @li @ref opus_decoder
  * @li @ref opus_repacketizer
+ * @li @ref opus_multistream
  * @li @ref opus_libinfo
  * @li @ref opus_custom
  */
@@ -135,10 +136,11 @@
   * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
   * <li>frame_size is the duration of the frame in samples (per channel)</li>
   * <li>packet is the byte array to which the compressed data is written</li>
-  * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended)</li>
+  * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended).
+  *     Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.</li>
   * </ul>
   *
-  * opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet.
+  * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
   * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
   * is 1 byte, then the packet does not need to be transmitted (DTX).
   *
@@ -161,6 +163,11 @@
   */
 typedef struct OpusEncoder OpusEncoder;
 
+/** Gets the size of an <code>OpusEncoder</code> structure.
+  * @param[in] channels <tt>int</tt>: Number of channels.
+  *                                   This must be 1 or 2.
+  * @returns The size in bytes.
+  */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels);
 
 /**
@@ -188,11 +195,13 @@
  *
  * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).
  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
- * @param [in] channels <tt>int</tt>: Number of channels (1/2) in input signal
+ *                                     This must be one of 8000, 12000, 16000,
+ *                                     24000, or 48000.
+ * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
  * @param [in] application <tt>int</tt>: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY)
  * @param [out] error <tt>int*</tt>: @ref opus_errorcodes
  * @note Regardless of the sampling rate and number channels selected, the Opus encoder
- * can switch to a lower audio audio bandwidth or number of channels if the bitrate
+ * can switch to a lower audio bandwidth or number of channels if the bitrate
  * selected is too low. This also means that it is safe to always use 48 kHz stereo input
  * and let the encoder optimize the encoding.
  */
@@ -204,15 +213,17 @@
 );
 
 /** Initializes a previously allocated encoder state
-  * The memory pointed to by st must be the size returned by opus_encoder_get_size.
+  * The memory pointed to by st must be at least the size returned by opus_encoder_get_size().
   * This is intended for applications which use their own allocator instead of malloc.
   * @see opus_encoder_create(),opus_encoder_get_size()
-  * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
   * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
   * @param [in] Fs <tt>opus_int32</tt>: Sampling rate of input signal (Hz)
-  * @param [in] channels <tt>int</tt>: Number of channels (1/2) in input signal
+ *                                      This must be one of 8000, 12000, 16000,
+ *                                      24000, or 48000.
+  * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) in input signal
   * @param [in] application <tt>int</tt>: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY)
-  * @retval OPUS_OK Success or @ref opus_errorcodes
+  * @retval #OPUS_OK Success or @ref opus_errorcodes
   */
 OPUS_EXPORT int opus_encoder_init(
     OpusEncoder *st,
@@ -222,16 +233,32 @@
 ) OPUS_ARG_NONNULL(1);
 
 /** Encodes an Opus frame.
-  * The passed frame_size must an opus frame size for the encoder's sampling rate.
-  * For example, at 48kHz the permitted values are 120, 240, 480, 960, 1920, and 2880.
-  * Passing in a duration of less than 10ms (480 samples at 48kHz) will
-  * prevent the encoder from using the LPC or hybrid modes.
   * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
   * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
-  * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
-  * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
-  * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
-  * @returns length of the data payload (in bytes) or @ref opus_errorcodes
+  * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+  *                                      input signal.
+  *                                      This must be an Opus frame size for
+  *                                      the encoder's sampling rate.
+  *                                      For example, at 48 kHz the permitted
+  *                                      values are 120, 240, 480, 960, 1920,
+  *                                      and 2880.
+  *                                      Passing in a duration of less than
+  *                                      10 ms (480 samples at 48 kHz) will
+  *                                      prevent the encoder from using the LPC
+  *                                      or hybrid modes.
+  * @param [out] data <tt>unsigned char*</tt>: Output payload.
+  *                                            This must contain storage for at
+  *                                            least \a max_data_bytes.
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+  *                                                 memory for the output
+  *                                                 payload. This may be
+  *                                                 used to impose an upper limit on
+  *                                                 the instant bitrate, but should
+  *                                                 not be used as the only bitrate
+  *                                                 control. Use #OPUS_SET_BITRATE to
+  *                                                 control the bitrate.
+  * @returns The length of the encoded packet (in bytes) on success or a
+  *          negative error code (see @ref opus_errorcodes) on failure.
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
     OpusEncoder *st,
@@ -242,10 +269,6 @@
 ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
 
 /** Encodes an Opus frame from floating point input.
-  * The passed frame_size must an opus frame size for the encoder's sampling rate.
-  * For example, at 48kHz the permitted values are 120, 240, 480, 960, 1920, and 2880.
-  * Passing in a duration of less than 10ms (480 samples at 48kHz) will
-  * prevent the encoder from using the LPC or hybrid modes.
   * @param [in] st <tt>OpusEncoder*</tt>: Encoder state
   * @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
   *          Samples with a range beyond +/-1.0 are supported but will
@@ -253,10 +276,30 @@
   *          only be used if it is known that the far end supports
   *          extended dynamic range.
   *          length is frame_size*channels*sizeof(float)
-  * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
-  * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
-  * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
-  * @returns length of the data payload (in bytes) or @ref opus_errorcodes
+  * @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
+  *                                      input signal.
+  *                                      This must be an Opus frame size for
+  *                                      the encoder's sampling rate.
+  *                                      For example, at 48 kHz the permitted
+  *                                      values are 120, 240, 480, 960, 1920,
+  *                                      and 2880.
+  *                                      Passing in a duration of less than
+  *                                      10 ms (480 samples at 48 kHz) will
+  *                                      prevent the encoder from using the LPC
+  *                                      or hybrid modes.
+  * @param [out] data <tt>unsigned char*</tt>: Output payload.
+  *                                            This must contain storage for at
+  *                                            least \a max_data_bytes.
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+  *                                                 memory for the output
+  *                                                 payload. This may be
+  *                                                 used to impose an upper limit on
+  *                                                 the instant bitrate, but should
+  *                                                 not be used as the only bitrate
+  *                                                 control. Use #OPUS_SET_BITRATE to
+  *                                                 control the bitrate.
+  * @returns The length of the encoded packet (in bytes) on success or a
+  *          negative error code (see @ref opus_errorcodes) on failure.
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float(
     OpusEncoder *st,
@@ -266,7 +309,7 @@
     opus_int32 max_data_bytes
 ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
 
-/** Frees an OpusEncoder allocated by opus_encoder_create.
+/** Frees an <code>OpusEncoder</code> allocated by opus_encoder_create().
   * @param[in] st <tt>OpusEncoder*</tt>: State to be freed.
   */
 OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
@@ -275,6 +318,11 @@
   *
   * Generally the request and subsequent arguments are generated
   * by a convenience macro.
+  * @param st <tt>OpusEncoder*</tt>: Encoder state.
+  * @param request This and all remaining parameters should be replaced by one
+  *                of the convenience macros in @ref opus_genericctls or
+  *                @ref opus_encoderctls.
+  * @see opus_genericctls
   * @see opus_encoderctls
   */
 OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
@@ -295,7 +343,7 @@
   * where
   * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000
   * @li channels is the number of channels (1 or 2)
-  * @li error will hold the error code in case or failure (or OPUS_OK on success)
+  * @li error will hold the error code in case of failure (or #OPUS_OK on success)
   * @li the return value is a newly created decoder state to be used for decoding
   *
   * While opus_decoder_create() allocates memory for the state, it's also possible
@@ -326,7 +374,7 @@
   * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array
   *
   * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet.
-  * If that value is negative, then an error has occured. This can occur if the packet is corrupted or if the audio
+  * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio
   * buffer is too small to hold the decoded audio.
   *
   * Opus is a stateful codec with overlapping blocks and as a result Opus
@@ -350,16 +398,19 @@
   */
 typedef struct OpusDecoder OpusDecoder;
 
-/** Gets the size of an OpusDecoder structure.
-  * @param [in] channels <tt>int</tt>: Number of channels
-  * @returns size
+/** Gets the size of an <code>OpusDecoder</code> structure.
+  * @param [in] channels <tt>int</tt>: Number of channels.
+  *                                    This must be 1 or 2.
+  * @returns The size in bytes.
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels);
 
 /** Allocates and initializes a decoder state.
-  * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz)
-  * @param [in] channels <tt>int</tt>: Number of channels (1/2) to decode
-  * @param [out] error <tt>int*</tt>: OPUS_OK Success or @ref opus_errorcodes
+  * @param [in] Fs <tt>opus_int32</tt>: Sample rate to decode at (Hz).
+  *                                     This must be one of 8000, 12000, 16000,
+  *                                     24000, or 48000.
+  * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+  * @param [out] error <tt>int*</tt>: #OPUS_OK Success or @ref opus_errorcodes
   *
   * Internally Opus stores data at 48000 Hz, so that should be the default
   * value for Fs. However, the decoder can efficiently decode to buffers
@@ -376,13 +427,15 @@
 );
 
 /** Initializes a previously allocated decoder state.
-  * The state must be the size returned by opus_decoder_get_size.
+  * The state must be at least the size returned by opus_decoder_get_size().
   * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size
-  * To reset a previously initialized state use the OPUS_RESET_STATE CTL.
+  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
   * @param [in] st <tt>OpusDecoder*</tt>: Decoder state.
-  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz)
-  * @param [in] channels <tt>int</tt>: Number of channels (1/2) to decode
-  * @retval OPUS_OK Success or @ref opus_errorcodes
+  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate to decode to (Hz).
+  *                                     This must be one of 8000, 12000, 16000,
+  *                                     24000, or 48000.
+  * @param [in] channels <tt>int</tt>: Number of channels (1 or 2) to decode
+  * @retval #OPUS_OK Success or @ref opus_errorcodes
   */
 OPUS_EXPORT int opus_decoder_init(
     OpusDecoder *st,
@@ -390,16 +443,20 @@
     int channels
 ) OPUS_ARG_NONNULL(1);
 
-/** Decode an Opus frame
+/** Decode an Opus packet.
   * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
   * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
   * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
   *  is frame_size*channels*sizeof(opus_int16)
-  * @param [in] frame_size Number of samples per channel of available space in *pcm,
-  *  if less than the maximum frame size (120ms) some frames can not be decoded
-  * @param [in] decode_fec <tt>int</tt>: Flag (0/1) to request that any in-band forward error correction data be
-  *  decoded. If no such data is available the frame is decoded as if it were lost.
+  * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+  *  If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+  *  not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+  *  then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+  *  decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+  *  FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+  * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
+  *  decoded. If no such data is available, the frame is decoded as if it were lost.
   * @returns Number of decoded samples or @ref opus_errorcodes
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
@@ -411,15 +468,19 @@
     int decode_fec
 ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
 
-/** Decode an opus frame with floating point output
+/** Decode an Opus packet with floating point output.
   * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
   * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
   * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
   *  is frame_size*channels*sizeof(float)
-  * @param [in] frame_size Number of samples per channel of available space in *pcm,
-  *  if less than the maximum frame size (120ms) some frames can not be decoded
-  * @param [in] decode_fec <tt>int</tt>: Flag (0/1) to request that any in-band forward error correction data be
+  * @param [in] frame_size Number of samples per channel of available space in \a pcm.
+  *  If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
+  *  not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
+  *  then frame_size needs to be exactly the duration of audio that is missing, otherwise the
+  *  decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
+  *  FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
+  * @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
   *  decoded. If no such data is available the frame is decoded as if it were lost.
   * @returns Number of decoded samples or @ref opus_errorcodes
   */
@@ -436,11 +497,16 @@
   *
   * Generally the request and subsequent arguments are generated
   * by a convenience macro.
+  * @param st <tt>OpusDecoder*</tt>: Decoder state.
+  * @param request This and all remaining parameters should be replaced by one
+  *                of the convenience macros in @ref opus_genericctls or
+  *                @ref opus_decoderctls.
   * @see opus_genericctls
+  * @see opus_decoderctls
   */
 OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
 
-/** Frees an OpusDecoder allocated by opus_decoder_create.
+/** Frees an <code>OpusDecoder</code> allocated by opus_decoder_create().
   * @param[in] st <tt>OpusDecoder*</tt>: State to be freed.
   */
 OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
@@ -479,10 +545,13 @@
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1);
 
 /** Gets the number of samples per frame from an Opus packet.
-  * @param [in] data <tt>char*</tt>: Opus packet
-  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz
-  * @returns Number of samples per frame
-  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+  * @param [in] data <tt>char*</tt>: Opus packet.
+  *                                  This must contain at least one byte of
+  *                                  data.
+  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+  *                                     This must be a multiple of 400, or
+  *                                     inaccurate results will be returned.
+  * @returns Number of samples per frame.
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1);
 
@@ -502,6 +571,17 @@
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);
 
 /** Gets the number of samples of an Opus packet.
+  * @param [in] packet <tt>char*</tt>: Opus packet
+  * @param [in] len <tt>opus_int32</tt>: Length of packet
+  * @param [in] Fs <tt>opus_int32</tt>: Sampling rate in Hz.
+  *                                     This must be a multiple of 400, or
+  *                                     inaccurate results will be returned.
+  * @returns Number of samples
+  * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
+
+/** Gets the number of samples of an Opus packet.
   * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] packet <tt>char*</tt>: Opus packet
   * @param [in] len <tt>opus_int32</tt>: Length of packet
@@ -514,27 +594,304 @@
 /** @defgroup opus_repacketizer Repacketizer
   * @{
   *
-  * The repacketizer can be used to merge multiple Opus packets into a single packet
-  * or alternatively to split Opus packets that have previously been merged.
+  * The repacketizer can be used to merge multiple Opus packets into a single
+  * packet or alternatively to split Opus packets that have previously been
+  * merged. Splitting valid Opus packets is always guaranteed to succeed,
+  * whereas merging valid packets only succeeds if all frames have the same
+  * mode, bandwidth, and frame size, and when the total duration of the merged
+  * packet is no more than 120 ms.
+  * The repacketizer currently only operates on elementary Opus
+  * streams. It will not manipualte multistream packets successfully, except in
+  * the degenerate case where they consist of data from a single stream.
   *
+  * The repacketizing process starts with creating a repacketizer state, either
+  * by calling opus_repacketizer_create() or by allocating the memory yourself,
+  * e.g.,
+  * @code
+  * OpusRepacketizer *rp;
+  * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size());
+  * if (rp != NULL)
+  *     opus_repacketizer_init(rp);
+  * @endcode
+  *
+  * Then the application should submit packets with opus_repacketizer_cat(),
+  * extract new packets with opus_repacketizer_out() or
+  * opus_repacketizer_out_range(), and then reset the state for the next set of
+  * input packets via opus_repacketizer_init().
+  *
+  * For example, to split a sequence of packets into individual frames:
+  * @code
+  * unsigned char *data;
+  * int len;
+  * while (get_next_packet(&data, &len))
+  * {
+  *   unsigned char out[1276];
+  *   opus_int32 out_len;
+  *   int nb_frames;
+  *   int err;
+  *   int i;
+  *   err = opus_repacketizer_cat(rp, data, len);
+  *   if (err != OPUS_OK)
+  *   {
+  *     release_packet(data);
+  *     return err;
+  *   }
+  *   nb_frames = opus_repacketizer_get_nb_frames(rp);
+  *   for (i = 0; i < nb_frames; i++)
+  *   {
+  *     out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out));
+  *     if (out_len < 0)
+  *     {
+  *        release_packet(data);
+  *        return (int)out_len;
+  *     }
+  *     output_next_packet(out, out_len);
+  *   }
+  *   opus_repacketizer_init(rp);
+  *   release_packet(data);
+  * }
+  * @endcode
+  *
+  * Alternatively, to combine a sequence of frames into packets that each
+  * contain up to <code>TARGET_DURATION_MS</code> milliseconds of data:
+  * @code
+  * // The maximum number of packets with duration TARGET_DURATION_MS occurs
+  * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5)
+  * // packets.
+  * unsigned char *data[(TARGET_DURATION_MS*2/5)+1];
+  * opus_int32 len[(TARGET_DURATION_MS*2/5)+1];
+  * int nb_packets;
+  * unsigned char out[1277*(TARGET_DURATION_MS*2/2)];
+  * opus_int32 out_len;
+  * int prev_toc;
+  * nb_packets = 0;
+  * while (get_next_packet(data+nb_packets, len+nb_packets))
+  * {
+  *   int nb_frames;
+  *   int err;
+  *   nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]);
+  *   if (nb_frames < 1)
+  *   {
+  *     release_packets(data, nb_packets+1);
+  *     return nb_frames;
+  *   }
+  *   nb_frames += opus_repacketizer_get_nb_frames(rp);
+  *   // If adding the next packet would exceed our target, or it has an
+  *   // incompatible TOC sequence, output the packets we already have before
+  *   // submitting it.
+  *   // N.B., The nb_packets > 0 check ensures we've submitted at least one
+  *   // packet since the last call to opus_repacketizer_init(). Otherwise a
+  *   // single packet longer than TARGET_DURATION_MS would cause us to try to
+  *   // output an (invalid) empty packet. It also ensures that prev_toc has
+  *   // been set to a valid value. Additionally, len[nb_packets] > 0 is
+  *   // guaranteed by the call to opus_packet_get_nb_frames() above, so the
+  *   // reference to data[nb_packets][0] should be valid.
+  *   if (nb_packets > 0 && (
+  *       ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) ||
+  *       opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames >
+  *       TARGET_DURATION_MS*48))
+  *   {
+  *     out_len = opus_repacketizer_out(rp, out, sizeof(out));
+  *     if (out_len < 0)
+  *     {
+  *        release_packets(data, nb_packets+1);
+  *        return (int)out_len;
+  *     }
+  *     output_next_packet(out, out_len);
+  *     opus_repacketizer_init(rp);
+  *     release_packets(data, nb_packets);
+  *     data[0] = data[nb_packets];
+  *     len[0] = len[nb_packets];
+  *     nb_packets = 0;
+  *   }
+  *   err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]);
+  *   if (err != OPUS_OK)
+  *   {
+  *     release_packets(data, nb_packets+1);
+  *     return err;
+  *   }
+  *   prev_toc = data[nb_packets][0];
+  *   nb_packets++;
+  * }
+  * // Output the final, partial packet.
+  * if (nb_packets > 0)
+  * {
+  *   out_len = opus_repacketizer_out(rp, out, sizeof(out));
+  *   release_packets(data, nb_packets);
+  *   if (out_len < 0)
+  *     return (int)out_len;
+  *   output_next_packet(out, out_len);
+  * }
+  * @endcode
+  *
+  * An alternate way of merging packets is to simply call opus_repacketizer_cat()
+  * unconditionally until it fails. At that point, the merged packet can be
+  * obtained with opus_repacketizer_out() and the input packet for which
+  * opus_repacketizer_cat() needs to be re-added to a newly reinitialized
+  * repacketizer state.
   */
 
 typedef struct OpusRepacketizer OpusRepacketizer;
 
+/** Gets the size of an <code>OpusRepacketizer</code> structure.
+  * @returns The size in bytes.
+  */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void);
 
+/** (Re)initializes a previously allocated repacketizer state.
+  * The state must be at least the size returned by opus_repacketizer_get_size().
+  * This can be used for applications which use their own allocator instead of
+  * malloc().
+  * It must also be called to reset the queue of packets waiting to be
+  * repacketized, which is necessary if the maximum packet duration of 120 ms
+  * is reached or if you wish to submit packets with a different Opus
+  * configuration (coding mode, audio bandwidth, frame size, or channel count).
+  * Failure to do so will prevent a new packet from being added with
+  * opus_repacketizer_cat().
+  * @see opus_repacketizer_create
+  * @see opus_repacketizer_get_size
+  * @see opus_repacketizer_cat
+  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to
+  *                                       (re)initialize.
+  * @returns A pointer to the same repacketizer state that was passed in.
+  */
 OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
 
+/** Allocates memory and initializes the new repacketizer with
+ * opus_repacketizer_init().
+  */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void);
 
+/** Frees an <code>OpusRepacketizer</code> allocated by
+  * opus_repacketizer_create().
+  * @param[in] rp <tt>OpusRepacketizer*</tt>: State to be freed.
+  */
 OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
 
+/** Add a packet to the current repacketizer state.
+  * This packet must match the configuration of any packets already submitted
+  * for repacketization since the last call to opus_repacketizer_init().
+  * This means that it must have the same coding mode, audio bandwidth, frame
+  * size, and channel count.
+  * This can be checked in advance by examining the top 6 bits of the first
+  * byte of the packet, and ensuring they match the top 6 bits of the first
+  * byte of any previously submitted packet.
+  * The total duration of audio in the repacketizer state also must not exceed
+  * 120 ms, the maximum duration of a single packet, after adding this packet.
+  *
+  * The contents of the current repacketizer state can be extracted into new
+  * packets using opus_repacketizer_out() or opus_repacketizer_out_range().
+  *
+  * In order to add a packet with a different configuration or to add more
+  * audio beyond 120 ms, you must clear the repacketizer state by calling
+  * opus_repacketizer_init().
+  * If a packet is too large to add to the current repacketizer state, no part
+  * of it is added, even if it contains multiple frames, some of which might
+  * fit.
+  * If you wish to be able to add parts of such packets, you should first use
+  * another repacketizer to split the packet into pieces and add them
+  * individually.
+  * @see opus_repacketizer_out_range
+  * @see opus_repacketizer_out
+  * @see opus_repacketizer_init
+  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state to which to
+  *                                       add the packet.
+  * @param[in] data <tt>const unsigned char*</tt>: The packet data.
+  *                                                The application must ensure
+  *                                                this pointer remains valid
+  *                                                until the next call to
+  *                                                opus_repacketizer_init() or
+  *                                                opus_repacketizer_destroy().
+  * @param len <tt>opus_int32</tt>: The number of bytes in the packet data.
+  * @returns An error code indicating whether or not the operation succeeded.
+  * @retval #OPUS_OK The packet's contents have been added to the repacketizer
+  *                  state.
+  * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence,
+  *                              the packet's TOC sequence was not compatible
+  *                              with previously submitted packets (because
+  *                              the coding mode, audio bandwidth, frame size,
+  *                              or channel count did not match), or adding
+  *                              this packet would increase the total amount of
+  *                              audio stored in the repacketizer state to more
+  *                              than 120 ms.
+  */
 OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
 
+
+/** Construct a new packet from data previously submitted to the repacketizer
+  * state via opus_repacketizer_cat().
+  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+  *                                       construct the new packet.
+  * @param begin <tt>int</tt>: The index of the first frame in the current
+  *                            repacketizer state to include in the output.
+  * @param end <tt>int</tt>: One past the index of the last frame in the
+  *                          current repacketizer state to include in the
+  *                          output.
+  * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+  *                                                 store the output packet.
+  * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+  *                                    the output buffer. In order to guarantee
+  *                                    success, this should be at least
+  *                                    <code>1276</code> for a single frame,
+  *                                    or for multiple frames,
+  *                                    <code>1277*(end-begin)</code>.
+  *                                    However, <code>1*(end-begin)</code> plus
+  *                                    the size of all packet data submitted to
+  *                                    the repacketizer since the last call to
+  *                                    opus_repacketizer_init() or
+  *                                    opus_repacketizer_create() is also
+  *                                    sufficient, and possibly much smaller.
+  * @returns The total size of the output packet on success, or an error code
+  *          on failure.
+  * @retval #OPUS_BAD_ARG <code>[begin,end)</code> was an invalid range of
+  *                       frames (begin < 0, begin >= end, or end >
+  *                       opus_repacketizer_get_nb_frames()).
+  * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+  *                                complete output packet.
+  */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
 
+/** Return the total number of frames contained in packet data submitted to
+  * the repacketizer state so far via opus_repacketizer_cat() since the last
+  * call to opus_repacketizer_init() or opus_repacketizer_create().
+  * This defines the valid range of packets that can be extracted with
+  * opus_repacketizer_out_range() or opus_repacketizer_out().
+  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state containing the
+  *                                       frames.
+  * @returns The total number of frames contained in the packet data submitted
+  *          to the repacketizer state.
+  */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1);
 
+/** Construct a new packet from data previously submitted to the repacketizer
+  * state via opus_repacketizer_cat().
+  * This is a convenience routine that returns all the data submitted so far
+  * in a single packet.
+  * It is equivalent to calling
+  * @code
+  * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp),
+  *                             data, maxlen)
+  * @endcode
+  * @param rp <tt>OpusRepacketizer*</tt>: The repacketizer state from which to
+  *                                       construct the new packet.
+  * @param[out] data <tt>const unsigned char*</tt>: The buffer in which to
+  *                                                 store the output packet.
+  * @param maxlen <tt>opus_int32</tt>: The maximum number of bytes to store in
+  *                                    the output buffer. In order to guarantee
+  *                                    success, this should be at least
+  *                                    <code>1277*opus_repacketizer_get_nb_frames(rp)</code>.
+  *                                    However,
+  *                                    <code>1*opus_repacketizer_get_nb_frames(rp)</code>
+  *                                    plus the size of all packet data
+  *                                    submitted to the repacketizer since the
+  *                                    last call to opus_repacketizer_init() or
+  *                                    opus_repacketizer_create() is also
+  *                                    sufficient, and possibly much smaller.
+  * @returns The total size of the output packet on success, or an error code
+  *          on failure.
+  * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the
+  *                                complete output packet.
+  */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
 
 /**@}*/
diff --git a/include/opus_defines.h b/include/opus_defines.h
index 82a5f06..cdde061 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -63,20 +63,18 @@
 /** @cond OPUS_INTERNAL_DOC */
 /**Export control for opus functions */
 
-#if !defined(OPUS_EXPORT)
-
-#if defined(__GNUC__) && defined(OPUS_BUILD)
-# define OPUS_EXPORT __attribute__ ((visibility ("default")))
-#elif defined(WIN32) && !defined(__MINGW32__)
-# ifdef OPUS_BUILD
+#ifndef OPUS_EXPORT
+# if defined(__GNUC__) && defined(OPUS_BUILD)
+#  define OPUS_EXPORT __attribute__ ((visibility ("default")))
+# elif defined(WIN32) && !defined(__MINGW32__)
+#  ifdef OPUS_BUILD
 #   define OPUS_EXPORT __declspec(dllexport)
-# else
+#  else
 #   define OPUS_EXPORT
+#  endif
+# else
+#  define OPUS_EXPORT
 # endif
-#else
-# define OPUS_EXPORT
-#endif
-
 #endif
 
 # if !defined(OPUS_GNUC_PREREQ)
@@ -147,10 +145,14 @@
 #define OPUS_GET_FINAL_RANGE_REQUEST         4031
 #define OPUS_GET_PITCH_REQUEST               4033
 #define OPUS_SET_GAIN_REQUEST                4034
-#define OPUS_GET_GAIN_REQUEST                4045
+#define OPUS_GET_GAIN_REQUEST                4045 /* Should have been 4035 */
 #define OPUS_SET_LSB_DEPTH_REQUEST           4036
 #define OPUS_GET_LSB_DEPTH_REQUEST           4037
 
+#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
+
+/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
+
 /* Macros to trigger compilation errors when the wrong types are provided to a CTL */
 #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
 #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
@@ -505,6 +507,24 @@
   * </dl>
   * @hideinitializer */
 #define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
+/** Configures the depth of signal being encoded.
+  * This is a hint which helps the encoder identify silence and near-silence.
+  * @see OPUS_GET_LSB_DEPTH
+  * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
+  *                                   (default: 24).
+  * @hideinitializer */
+#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured signal depth.
+  * @see OPUS_SET_LSB_DEPTH
+  * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
+  *                                      24 (default: 24).
+  * @hideinitializer */
+#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
+
+/** Gets the duration (in samples) of the last packet successfully decoded or concealed.
+  * @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
+  * @hideinitializer */
+#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
 /**@}*/
 
 /** @defgroup opus_genericctls Generic CTLs
@@ -584,19 +604,6 @@
   * @hideinitializer */
 #define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)
 
-/** Configures the depth of signal being encoded.
-  * This is a hint which helps the encoder identify silence and near-silence.
-  * @see OPUS_GET_LSB_DEPTH
-  * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
-  *                                   (default: 24).
-  * @hideinitializer */
-#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x)
-/** Gets the encoder's configured signal depth.
-  * @see OPUS_SET_LSB_DEPTH
-  * @param[out] x <tt>opus_int32 *</tt>: Input precision in bits, between 8 and
-  *                                      24 (default: 24).
-  * @hideinitializer */
-#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x)
 /**@}*/
 
 /** @defgroup opus_decoderctls Decoder related CTLs
diff --git a/include/opus_multistream.h b/include/opus_multistream.h
index 5e5364a..658067f 100644
--- a/include/opus_multistream.h
+++ b/include/opus_multistream.h
@@ -39,132 +39,592 @@
 extern "C" {
 #endif
 
-typedef struct OpusMSEncoder OpusMSEncoder;
-typedef struct OpusMSDecoder OpusMSDecoder;
+/** @cond OPUS_INTERNAL_DOC */
 
+/** Macros to trigger compilation errors when the wrong types are provided to a
+  * CTL. */
+/**@{*/
 #define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
 #define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
+/**@}*/
 
+/** These are the actual encoder and decoder CTL ID numbers.
+  * They should not be used directly by applications.
+  * In general, SETs should be even and GETs should be odd.*/
+/**@{*/
 #define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
 #define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
+/**@}*/
 
+/** @endcond */
+
+/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
+  *
+  * These are convenience macros that are specific to the
+  * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
+  * interface.
+  * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
+  * @ref opus_decoderctls may be applied to a multistream encoder or decoder as
+  * well.
+  * In addition, you may retrieve the encoder or decoder state for an specific
+  * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
+  * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
+  */
+/**@{*/
+
+/** Gets the encoder state for an individual stream of a multistream encoder.
+  * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
+  *                                   wish to retrieve.
+  *                                   This must be non-negative and less than
+  *                                   the <code>streams</code> parameter used
+  *                                   to initialize the encoder.
+  * @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given
+  *                                       encoder state.
+  * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+  * @hideinitializer
+  */
 #define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
+
+/** Gets the decoder state for an individual stream of a multistream decoder.
+  * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
+  *                                   wish to retrieve.
+  *                                   This must be non-negative and less than
+  *                                   the <code>streams</code> parameter used
+  *                                   to initialize the decoder.
+  * @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given
+  *                                       decoder state.
+  * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
+  * @hideinitializer
+  */
 #define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
 
-/** Allocate and initialize a multistream encoder state object.
- *  Call opus_multistream_encoder_destroy() to release
- *  this object when finished. */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
-      opus_int32 Fs,            /**< Sampling rate of input signal (Hz) */
-      int channels,             /**< Number of channels in the input signal */
-      int streams,              /**< Total number of streams to encode from the input */
-      int coupled_streams,      /**< Number of coupled (stereo) streams to encode */
-      const unsigned char *mapping, /**< Encoded mapping between channels and streams */
-      int application,          /**< Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
-      int *error                /**< Error code */
-) OPUS_ARG_NONNULL(5);
+/**@}*/
 
-/** Initialize an already allocated multistream encoder state. */
-OPUS_EXPORT int opus_multistream_encoder_init(
-      OpusMSEncoder *st,        /**< Encoder state */
-      opus_int32 Fs,            /**< Sampling rate of input signal (Hz) */
-      int channels,             /**< Number of channels in the input signal */
-      int streams,              /**< Total number of streams to encode from the input */
-      int coupled_streams,      /**< Number of coupled (stereo) streams to encode */
-      const unsigned char *mapping, /**< Encoded mapping between channels and streams */
-      int application           /**< Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+/** @defgroup opus_multistream Opus Multistream API
+  * @{
+  *
+  * The multistream API allows individual Opus streams to be combined into a
+  * single packet, enabling support for up to 255 channels. Unlike an
+  * elementary Opus stream, the encoder and decoder must negotiate the channel
+  * configuration before the decoder can successfully interpret the data in the
+  * packets produced by the encoder. Some basic information, such as packet
+  * duration, can be computed without any special negotiation.
+  *
+  * The format for multistream Opus packets is defined in the
+  * <a href="http://tools.ietf.org/html/draft-terriberry-oggopus">Ogg
+  * encapsulation specification</a> and is based on the self-delimited Opus
+  * framing described in Appendix B of <a href="http://tools.ietf.org/html/rfc6716">RFC 6716</a>.
+  * Normal Opus packets are just a degenerate case of multistream Opus packets,
+  * and can be encoded or decoded with the multistream API by setting
+  * <code>streams</code> to <code>1</code> when initializing the encoder or
+  * decoder.
+  *
+  * Multistream Opus streams can contain up to 255 elementary Opus streams.
+  * These may be either "uncoupled" or "coupled", indicating that the decoder
+  * is configured to decode them to either 1 or 2 channels, respectively.
+  * The streams are ordered so that all coupled streams appear at the
+  * beginning.
+  *
+  * A <code>mapping</code> table defines which decoded channel <code>i</code>
+  * should be used for each input/output (I/O) channel <code>j</code>. This table is
+  * typically provided as an unsigned char array.
+  * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
+  * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
+  * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
+  * is even, or  as the right channel of stream <code>(i/2)</code> if
+  * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
+  * mono in stream <code>(i - coupled_streams)</code>, unless it has the special
+  * value 255, in which case it is omitted from the encoding entirely (the
+  * decoder will reproduce it as silence). Each value <code>i</code> must either
+  * be the special value 255 or be less than <code>streams + coupled_streams</code>.
+  *
+  * The output channels specified by the encoder
+  * should use the
+  * <a href="http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-800004.3.9">Vorbis
+  * channel ordering</a>. A decoder may wish to apply an additional permutation
+  * to the mapping the encoder used to achieve a different output channel
+  * order (e.g. for outputing in WAV order).
+  *
+  * Each multistream packet contains an Opus packet for each stream, and all of
+  * the Opus packets in a single multistream packet must have the same
+  * duration. Therefore the duration of a multistream packet can be extracted
+  * from the TOC sequence of the first stream, which is located at the
+  * beginning of the packet, just like an elementary Opus stream:
+  *
+  * @code
+  * int nb_samples;
+  * int nb_frames;
+  * nb_frames = opus_packet_get_nb_frames(data, len);
+  * if (nb_frames < 1)
+  *   return nb_frames;
+  * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
+  * @endcode
+  *
+  * The general encoding and decoding process proceeds exactly the same as in
+  * the normal @ref opus_encoder and @ref opus_decoder APIs.
+  * See their documentation for an overview of how to use the corresponding
+  * multistream functions.
+  */
 
-/** Returns length of the data payload (in bytes) or a negative error code */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
-    OpusMSEncoder *st,          /**< Encoder state */
-    const opus_int16 *pcm,      /**< Input signal as interleaved samples. Length is frame_size*channels */
-    int frame_size,             /**< Number of samples per frame of input signal */
-    unsigned char *data,        /**< Output buffer for the compressed payload (no more than max_data_bytes long) */
-    opus_int32 max_data_bytes   /**< Allocated memory for payload; don't use for controlling bitrate */
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+/** Opus multistream encoder state.
+  * This contains the complete state of a multistream Opus encoder.
+  * It is position independent and can be freely copied.
+  * @see opus_multistream_encoder_create
+  * @see opus_multistream_encoder_init
+  */
+typedef struct OpusMSEncoder OpusMSEncoder;
 
-/** Returns length of the data payload (in bytes) or a negative error code. */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
-      OpusMSEncoder *st,        /**< Encoder state */
-      const float *pcm,         /**< Input signal interleaved in channel order. length is frame_size*channels */
-      int frame_size,           /**< Number of samples per frame of input signal */
-      unsigned char *data,      /**< Output buffer for the compressed payload (no more than max_data_bytes long) */
-      opus_int32 max_data_bytes /**< Allocated memory for payload; don't use for controlling bitrate */
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+/** Opus multistream decoder state.
+  * This contains the complete state of a multistream Opus decoder.
+  * It is position independent and can be freely copied.
+  * @see opus_multistream_decoder_create
+  * @see opus_multistream_decoder_init
+  */
+typedef struct OpusMSDecoder OpusMSDecoder;
+
+/**\name Multistream encoder functions */
+/**@{*/
 
 /** Gets the size of an OpusMSEncoder structure.
-  * @returns size
+  * @param streams <tt>int</tt>: The total number of streams to encode from the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+  *                                      to encode.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      encoded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @returns The size in bytes on success, or a negative error code
+  *          (see @ref opus_errorcodes) on error.
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
-      int streams,              /**< Total number of coded streams */
-      int coupled_streams       /**< Number of coupled (stereo) streams */
+      int streams,
+      int coupled_streams
 );
 
-/** Deallocate a multstream encoder state */
-OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
-
-/** Get or set options on a multistream encoder state */
-OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
-
-/** Allocate and initialize a multistream decoder state object.
- *  Call opus_multistream_decoder_destroy() to release
- *  this object when finished. */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
-      opus_int32 Fs,            /**< Sampling rate to decode at (Hz) */
-      int channels,             /**< Number of channels to decode */
-      int streams,              /**< Total number of coded streams in the multistream */
-      int coupled_streams,      /**< Number of coupled (stereo) streams in the multistream */
-      const unsigned char *mapping, /**< Stream to channel mapping table */
-      int *error                /**< Error code */
+/** Allocates and initializes a multistream encoder state.
+  * Call opus_multistream_encoder_destroy() to release
+  * this object when finished.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels in the input signal.
+  *                               This must be at most 255.
+  *                               It may be greater than the number of
+  *                               coded channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams to encode from the
+  *                              input.
+  *                              This must be no more than the number of channels.
+  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+  *                                      to encode.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      encoded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than the number of input channels.
+  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+  *                    encoded channels to input channels, as described in
+  *                    @ref opus_multistream. As an extra constraint, the
+  *                    multistream encoder does not allow encoding coupled
+  *                    streams for which one channel is unused since this
+  *                    is never a good idea.
+  * @param application <tt>int</tt>: The target encoder application.
+  *                                  This must be one of the following:
+  * <dl>
+  * <dt>#OPUS_APPLICATION_VOIP</dt>
+  * <dd>Process signal for improved speech intelligibility.</dd>
+  * <dt>#OPUS_APPLICATION_AUDIO</dt>
+  * <dd>Favor faithfulness to the original input.</dd>
+  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+  * <dd>Configure the minimum possible coding delay by disabling certain modes
+  * of operation.</dd>
+  * </dl>
+  * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
+  *                                   code (see @ref opus_errorcodes) on
+  *                                   failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
+      opus_int32 Fs,
+      int channels,
+      int streams,
+      int coupled_streams,
+      const unsigned char *mapping,
+      int application,
+      int *error
 ) OPUS_ARG_NONNULL(5);
 
-/** Intialize a previously allocated decoder state object. */
-OPUS_EXPORT int opus_multistream_decoder_init(
-      OpusMSDecoder *st,        /**< Encoder state */
-      opus_int32 Fs,            /**< Sample rate of input signal (Hz) */
-      int channels,             /**< Number of channels in the input signal */
-      int streams,              /**< Total number of coded streams */
-      int coupled_streams,      /**< Number of coupled (stereo) streams */
-      const unsigned char *mapping  /**< Stream to channel mapping table */
+/** Initialize a previously allocated multistream encoder state.
+  * The memory pointed to by \a st must be at least the size returned by
+  * opus_multistream_encoder_get_size().
+  * This is intended for applications which use their own allocator instead of
+  * malloc.
+  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+  * @see opus_multistream_encoder_create
+  * @see opus_multistream_encoder_get_size
+  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels in the input signal.
+  *                               This must be at most 255.
+  *                               It may be greater than the number of
+  *                               coded channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams to encode from the
+  *                              input.
+  *                              This must be no more than the number of channels.
+  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+  *                                      to encode.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      encoded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than the number of input channels.
+  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+  *                    encoded channels to input channels, as described in
+  *                    @ref opus_multistream. As an extra constraint, the
+  *                    multistream encoder does not allow encoding coupled
+  *                    streams for which one channel is unused since this
+  *                    is never a good idea.
+  * @param application <tt>int</tt>: The target encoder application.
+  *                                  This must be one of the following:
+  * <dl>
+  * <dt>#OPUS_APPLICATION_VOIP</dt>
+  * <dd>Process signal for improved speech intelligibility.</dd>
+  * <dt>#OPUS_APPLICATION_AUDIO</dt>
+  * <dd>Favor faithfulness to the original input.</dd>
+  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+  * <dd>Configure the minimum possible coding delay by disabling certain modes
+  * of operation.</dd>
+  * </dl>
+  * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+  *          on failure.
+  */
+OPUS_EXPORT int opus_multistream_encoder_init(
+      OpusMSEncoder *st,
+      opus_int32 Fs,
+      int channels,
+      int streams,
+      int coupled_streams,
+      const unsigned char *mapping,
+      int application
 ) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
 
-/** Returns the number of samples decoded or a negative error code */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
-    OpusMSDecoder *st,          /**< Decoder state */
-    const unsigned char *data,  /**< Input payload. Use a NULL pointer to indicate packet loss */
-    opus_int32 len,             /**< Number of bytes in payload */
-    opus_int16 *pcm,            /**< Output signal, samples interleaved in channel order . length is frame_size*channels */
-    int frame_size,             /**< Number of samples per frame of input signal */
-    int decode_fec              /**< Flag (0/1) to request that any in-band forward error correction data be */
-                                /**< decoded. If no such data is available the frame is decoded as if it were lost. */
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+/** Encodes a multistream Opus frame.
+  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+  * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
+  *                                            samples.
+  *                                            This must contain
+  *                                            <code>frame_size*channels</code>
+  *                                            samples.
+  * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+  *                                 signal.
+  *                                 This must be an Opus frame size for the
+  *                                 encoder's sampling rate.
+  *                                 For example, at 48 kHz the permitted values
+  *                                 are 120, 240, 480, 960, 1920, and 2880.
+  *                                 Passing in a duration of less than 10 ms
+  *                                 (480 samples at 48 kHz) will prevent the
+  *                                 encoder from using the LPC or hybrid modes.
+  * @param[out] data <tt>unsigned char*</tt>: Output payload.
+  *                                           This must contain storage for at
+  *                                           least \a max_data_bytes.
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+  *                                                 memory for the output
+  *                                                 payload. This may be
+  *                                                 used to impose an upper limit on
+  *                                                 the instant bitrate, but should
+  *                                                 not be used as the only bitrate
+  *                                                 control. Use #OPUS_SET_BITRATE to
+  *                                                 control the bitrate.
+  * @returns The length of the encoded packet (in bytes) on success or a
+  *          negative error code (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
+    OpusMSEncoder *st,
+    const opus_int16 *pcm,
+    int frame_size,
+    unsigned char *data,
+    opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
 
-/** Returns the number of samples decoded or a negative error code */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
-    OpusMSDecoder *st,          /**< Decoder state */
-    const unsigned char *data,  /**< Input payload buffer. Use a NULL pointer to indicate packet loss */
-    opus_int32 len,             /**< Number of payload bytes in data */
-    float *pcm,                 /**< Buffer for the output signal (interleaved iin channel order). length is frame_size*channels */
-    int frame_size,             /**< Number of samples per frame of input signal */
-    int decode_fec              /**< Flag (0/1) to request that any in-band forward error correction data be */
-                                /**< decoded. If no such data is available the frame is decoded as if it were lost. */
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+/** Encodes a multistream Opus frame from floating point input.
+  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+  * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
+  *                                       samples with a normal range of
+  *                                       +/-1.0.
+  *                                       Samples with a range beyond +/-1.0
+  *                                       are supported but will be clipped by
+  *                                       decoders using the integer API and
+  *                                       should only be used if it is known
+  *                                       that the far end supports extended
+  *                                       dynamic range.
+  *                                       This must contain
+  *                                       <code>frame_size*channels</code>
+  *                                       samples.
+  * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+  *                                 signal.
+  *                                 This must be an Opus frame size for the
+  *                                 encoder's sampling rate.
+  *                                 For example, at 48 kHz the permitted values
+  *                                 are 120, 240, 480, 960, 1920, and 2880.
+  *                                 Passing in a duration of less than 10 ms
+  *                                 (480 samples at 48 kHz) will prevent the
+  *                                 encoder from using the LPC or hybrid modes.
+  * @param[out] data <tt>unsigned char*</tt>: Output payload.
+  *                                           This must contain storage for at
+  *                                           least \a max_data_bytes.
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+  *                                                 memory for the output
+  *                                                 payload. This may be
+  *                                                 used to impose an upper limit on
+  *                                                 the instant bitrate, but should
+  *                                                 not be used as the only bitrate
+  *                                                 control. Use #OPUS_SET_BITRATE to
+  *                                                 control the bitrate.
+  * @returns The length of the encoded packet (in bytes) on success or a
+  *          negative error code (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
+      OpusMSEncoder *st,
+      const float *pcm,
+      int frame_size,
+      unsigned char *data,
+      opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
 
-/** Gets the size of an OpusMSDecoder structure.
-  * @returns size
+/** Frees an <code>OpusMSEncoder</code> allocated by
+  * opus_multistream_encoder_create().
+  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
+  */
+OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
+
+/** Perform a CTL function on a multistream Opus encoder.
+  *
+  * Generally the request and subsequent arguments are generated by a
+  * convenience macro.
+  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+  * @param request This and all remaining parameters should be replaced by one
+  *                of the convenience macros in @ref opus_genericctls,
+  *                @ref opus_encoderctls, or @ref opus_multistream_ctls.
+  * @see opus_genericctls
+  * @see opus_encoderctls
+  * @see opus_multistream_ctls
+  */
+OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+
+/**@}*/
+
+/**\name Multistream decoder functions */
+/**@{*/
+
+/** Gets the size of an <code>OpusMSDecoder</code> structure.
+  * @param streams <tt>int</tt>: The total number of streams coded in the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
+  *                                      (2 channel) streams.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      coded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @returns The size in bytes on success, or a negative error code
+  *          (see @ref opus_errorcodes) on error.
   */
 OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
-      int streams,              /**< Total number of coded streams */
-      int coupled_streams       /**< Number of coupled (stereo) streams */
+      int streams,
+      int coupled_streams
 );
 
-/** Get or set options on a multistream decoder state */
+/** Allocates and initializes a multistream decoder state.
+  * Call opus_multistream_decoder_destroy() to release
+  * this object when finished.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels to output.
+  *                               This must be at most 255.
+  *                               It may be different from the number of coded
+  *                               channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams coded in the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+  *                                      (2 channel) streams.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      coded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+  *                    coded channels to output channels, as described in
+  *                    @ref opus_multistream.
+  * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
+  *                                   code (see @ref opus_errorcodes) on
+  *                                   failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
+      opus_int32 Fs,
+      int channels,
+      int streams,
+      int coupled_streams,
+      const unsigned char *mapping,
+      int *error
+) OPUS_ARG_NONNULL(5);
+
+/** Intialize a previously allocated decoder state object.
+  * The memory pointed to by \a st must be at least the size returned by
+  * opus_multistream_encoder_get_size().
+  * This is intended for applications which use their own allocator instead of
+  * malloc.
+  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+  * @see opus_multistream_decoder_create
+  * @see opus_multistream_deocder_get_size
+  * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels to output.
+  *                               This must be at most 255.
+  *                               It may be different from the number of coded
+  *                               channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams coded in the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+  *                                      (2 channel) streams.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      coded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
+  *                    coded channels to output channels, as described in
+  *                    @ref opus_multistream.
+  * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+  *          on failure.
+  */
+OPUS_EXPORT int opus_multistream_decoder_init(
+      OpusMSDecoder *st,
+      opus_int32 Fs,
+      int channels,
+      int streams,
+      int coupled_streams,
+      const unsigned char *mapping
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+/** Decode a multistream Opus packet.
+  * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+  * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+  *                                                Use a <code>NULL</code>
+  *                                                pointer to indicate packet
+  *                                                loss.
+  * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+  * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+  *                                       samples.
+  *                                       This must contain room for
+  *                                       <code>frame_size*channels</code>
+  *                                       samples.
+  * @param frame_size <tt>int</tt>: The number of samples per channel of
+  *                                 available space in \a pcm.
+  *                                 If this is less than the maximum packet duration
+  *                                 (120 ms; 5760 for 48kHz), this function will not be capable
+  *                                 of decoding some packets. In the case of PLC (data==NULL)
+  *                                 or FEC (decode_fec=1), then frame_size needs to be exactly
+  *                                 the duration of audio that is missing, otherwise the
+  *                                 decoder will not be in the optimal state to decode the
+  *                                 next incoming packet. For the PLC and FEC cases, frame_size
+  *                                 <b>must</b> be a multiple of 2.5 ms.
+  * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+  *                                 forward error correction data be decoded.
+  *                                 If no such data is available, the frame is
+  *                                 decoded as if it were lost.
+  * @returns Number of samples decoded on success or a negative error code
+  *          (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
+    OpusMSDecoder *st,
+    const unsigned char *data,
+    opus_int32 len,
+    opus_int16 *pcm,
+    int frame_size,
+    int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode a multistream Opus packet with floating point output.
+  * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+  * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+  *                                                Use a <code>NULL</code>
+  *                                                pointer to indicate packet
+  *                                                loss.
+  * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+  * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+  *                                       samples.
+  *                                       This must contain room for
+  *                                       <code>frame_size*channels</code>
+  *                                       samples.
+  * @param frame_size <tt>int</tt>: The number of samples per channel of
+  *                                 available space in \a pcm.
+  *                                 If this is less than the maximum packet duration
+  *                                 (120 ms; 5760 for 48kHz), this function will not be capable
+  *                                 of decoding some packets. In the case of PLC (data==NULL)
+  *                                 or FEC (decode_fec=1), then frame_size needs to be exactly
+  *                                 the duration of audio that is missing, otherwise the
+  *                                 decoder will not be in the optimal state to decode the
+  *                                 next incoming packet. For the PLC and FEC cases, frame_size
+  *                                 <b>must</b> be a multiple of 2.5 ms.
+  * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+  *                                 forward error correction data be decoded.
+  *                                 If no such data is available, the frame is
+  *                                 decoded as if it were lost.
+  * @returns Number of samples decoded on success or a negative error code
+  *          (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
+    OpusMSDecoder *st,
+    const unsigned char *data,
+    opus_int32 len,
+    float *pcm,
+    int frame_size,
+    int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Perform a CTL function on a multistream Opus decoder.
+  *
+  * Generally the request and subsequent arguments are generated by a
+  * convenience macro.
+  * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+  * @param request This and all remaining parameters should be replaced by one
+  *                of the convenience macros in @ref opus_genericctls,
+  *                @ref opus_decoderctls, or @ref opus_multistream_ctls.
+  * @see opus_genericctls
+  * @see opus_decoderctls
+  * @see opus_multistream_ctls
+  */
 OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
 
-/** Deallocate a multistream decoder state object */
+/** Frees an <code>OpusMSDecoder</code> allocated by
+  * opus_multistream_decoder_create().
+  * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
+  */
 OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
 
+/**@}*/
+
+/**@}*/
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/opus-uninstalled.pc.in b/opus-uninstalled.pc.in
index 7361028..36e8db6 100644
--- a/opus-uninstalled.pc.in
+++ b/opus-uninstalled.pc.in
@@ -1,12 +1,12 @@
-# opus codec reference implementation uninstalled pkg-config file
+# Opus codec reference implementation uninstalled pkg-config file
 
 libdir=${pcfiledir}/.libs
 includedir=${pcfiledir}
 
 Name: opus uninstalled
-Description: Opus IETF audio codec (not installed)
+Description: Opus IETF audio codec (not installed, @PC_BUILD@)
 Version: @VERSION@
 Requires:
 Conflicts:
-Libs: ${libdir}/libopus.a
-Cflags: -I${includedir}/include
+Libs: ${libdir}/libopus.a @PC_LIBM@
+Cflags: -I${pcfiledir}/@top_srcdir@/include
diff --git a/opus.m4 b/opus.m4
index 20f166b..47f5ec4 100644
--- a/opus.m4
+++ b/opus.m4
@@ -102,7 +102,7 @@
        echo "*** If you have an old version installed, it is best to remove it, although"
        echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
        [ echo "*** The test program failed to compile or link. See the file config.log for the"
-       echo "*** exact error that occured. This usually means Opus was incorrectly installed"
+       echo "*** exact error that occurred. This usually means Opus was incorrectly installed"
        echo "*** or that you have moved Opus since it was installed." ])
        CFLAGS="$ac_save_CFLAGS"
        LIBS="$ac_save_LIBS"
diff --git a/opus.pc.in b/opus.pc.in
index f702969..b7d4083 100644
--- a/opus.pc.in
+++ b/opus.pc.in
@@ -1,4 +1,4 @@
-# opus codec reference implementation pkg-config file
+# Opus codec reference implementation pkg-config file
 
 prefix=@prefix@
 exec_prefix=@exec_prefix@
@@ -6,10 +6,11 @@
 includedir=@includedir@
 
 Name: Opus
-Description: Opus IETF low-latency audio codec
+Description: Opus IETF audio codec (@PC_BUILD@ build)
 URL: http://opus-codec.org/
 Version: @VERSION@
 Requires:
 Conflicts:
 Libs: -L${libdir} -lopus
+Libs.private: @PC_LIBM@
 Cflags: -I${includedir}/opus
diff --git a/opus_headers.mk b/opus_headers.mk
new file mode 100644
index 0000000..f160710
--- /dev/null
+++ b/opus_headers.mk
@@ -0,0 +1,4 @@
+OPUS_HEAD = \
+include/opus.h \
+include/opus_multistream.h \
+src/opus_private.h
diff --git a/opus_sources.mk b/opus_sources.mk
new file mode 100644
index 0000000..384b036
--- /dev/null
+++ b/opus_sources.mk
@@ -0,0 +1,5 @@
+OPUS_SOURCES = src/opus.c \
+src/opus_decoder.c \
+src/opus_encoder.c \
+src/opus_multistream.c \
+src/repacketizer.c
diff --git a/silk/API.h b/silk/API.h
index c77ad2f..4b8ca12 100644
--- a/silk/API.h
+++ b/silk/API.h
@@ -67,14 +67,6 @@
     silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
 );
 
-/***************************************/
-/* Read control structure from encoder */
-/***************************************/
-opus_int silk_QueryEncoder(                             /* O    Returns error code                              */
-    const void                      *encState,          /* I    State                                           */
-    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
-);
-
 /**************************/
 /* Encode frame with Silk */
 /**************************/
diff --git a/silk/NLSF_stabilize.c b/silk/NLSF_stabilize.c
index fc642af..7498b54 100644
--- a/silk/NLSF_stabilize.c
+++ b/silk/NLSF_stabilize.c
@@ -31,7 +31,7 @@
 
 /* NLSF stabilizer:                                         */
 /*                                                          */
-/* - Moves NLSFs futher apart if they are too close         */
+/* - Moves NLSFs further apart if they are too close        */
 /* - Moves NLSFs away from borders if they are too close    */
 /* - High effort to achieve a modification with minimum     */
 /*     Euclidean distance to input vector                   */
diff --git a/silk/PLC.c b/silk/PLC.c
index 1b93d06..8d54729 100644
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -30,6 +30,7 @@
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 #include "PLC.h"
 
 #define NB_ATT 2
@@ -178,12 +179,17 @@
     opus_int16 rand_scale_Q14;
     opus_int16 *B_Q14, *exc_buf_ptr;
     opus_int32 *sLPC_Q14_ptr;
-    opus_int16 exc_buf[ 2 * MAX_SUB_FRAME_LENGTH ];
+    VARDECL( opus_int16, exc_buf );
     opus_int16 A_Q12[ MAX_LPC_ORDER ];
-    opus_int16 sLTP[ MAX_FRAME_LENGTH ];
-    opus_int32 sLTP_Q14[ 2 * MAX_FRAME_LENGTH ];
+    VARDECL( opus_int16, sLTP );
+    VARDECL( opus_int32, sLTP_Q14 );
     silk_PLC_struct *psPLC = &psDec->sPLC;
     opus_int32 prevGain_Q10[2];
+    SAVE_STACK;
+
+    ALLOC( exc_buf, 2*psPLC->subfr_length, opus_int16 );
+    ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
+    ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
 
     prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6);
     prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6);
@@ -354,9 +360,10 @@
     for( i = 0; i < MAX_NB_SUBFR; i++ ) {
         psDecCtrl->pitchL[ i ] = lag;
     }
+    RESTORE_STACK;
 }
 
-/* Glues concealed frames with new good recieved frames */
+/* Glues concealed frames with new good received frames */
 void silk_PLC_glue_frames(
     silk_decoder_state                  *psDec,             /* I/O decoder state        */
     opus_int16                          frame[],            /* I/O signal               */
diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h
index 72ec26a..daa5fd0 100644
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -313,7 +313,7 @@
     opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */
     const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */
     const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */
-    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceeding samples)   */
+    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */
     const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */
     const opus_int              D                   /* I    Order                                                       */
 );
@@ -379,7 +379,7 @@
     }
 }
 
-/* Allocate opus_int16 alligned to 4-byte memory address */
+/* Allocate opus_int16 aligned to 4-byte memory address */
 #if EMBEDDED_ARM
 #define silk_DWORD_ALIGN __attribute__((aligned(4)))
 #else
diff --git a/silk/control_audio_bandwidth.c b/silk/control_audio_bandwidth.c
index a9af913..b645dd5 100644
--- a/silk/control_audio_bandwidth.c
+++ b/silk/control_audio_bandwidth.c
@@ -80,6 +80,8 @@
                 } else {
                    if( psEncC->sLP.transition_frame_no <= 0 ) {
                        encControl->switchReady = 1;
+                       /* Make room for redundancy */
+                       encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
                    } else {
                        /* Direction: down (at double speed) */
                        psEncC->sLP.mode = -2;
@@ -106,6 +108,8 @@
                 } else {
                    if( psEncC->sLP.mode == 0 ) {
                        encControl->switchReady = 1;
+                       /* Make room for redundancy */
+                       encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
                    } else {
                        /* Direction: up */
                        psEncC->sLP.mode = 1;
diff --git a/silk/control_codec.c b/silk/control_codec.c
index d0ed528..ecc338c 100644
--- a/silk/control_codec.c
+++ b/silk/control_codec.c
@@ -38,18 +38,18 @@
 #include "tuning_parameters.h"
 #include "pitch_est_defines.h"
 
-opus_int silk_setup_resamplers(
+static opus_int silk_setup_resamplers(
     silk_encoder_state_Fxx          *psEnc,             /* I/O                      */
     opus_int                        fs_kHz              /* I                        */
 );
 
-opus_int silk_setup_fs(
+static opus_int silk_setup_fs(
     silk_encoder_state_Fxx          *psEnc,             /* I/O                      */
     opus_int                        fs_kHz,             /* I                        */
     opus_int                        PacketSize_ms       /* I                        */
 );
 
-opus_int silk_setup_complexity(
+static opus_int silk_setup_complexity(
     silk_encoder_state              *psEncC,            /* I/O                      */
     opus_int                        Complexity          /* I                        */
 );
@@ -131,7 +131,7 @@
     return ret;
 }
 
-opus_int silk_setup_resamplers(
+static opus_int silk_setup_resamplers(
     silk_encoder_state_Fxx          *psEnc,             /* I/O                      */
     opus_int                         fs_kHz              /* I                        */
 )
@@ -186,7 +186,7 @@
     return ret;
 }
 
-opus_int silk_setup_fs(
+static opus_int silk_setup_fs(
     silk_encoder_state_Fxx          *psEnc,             /* I/O                      */
     opus_int                        fs_kHz,             /* I                        */
     opus_int                        PacketSize_ms       /* I                        */
@@ -299,7 +299,7 @@
     return ret;
 }
 
-opus_int silk_setup_complexity(
+static opus_int silk_setup_complexity(
     silk_encoder_state              *psEncC,            /* I/O                      */
     opus_int                        Complexity          /* I                        */
 )
diff --git a/silk/dec_API.c b/silk/dec_API.c
index 60beef6..68403b7 100644
--- a/silk/dec_API.c
+++ b/silk/dec_API.c
@@ -30,6 +30,7 @@
 #endif
 #include "API.h"
 #include "main.h"
+#include "stack_alloc.h"
 
 /************************/
 /* Decoder Super Struct */
@@ -85,14 +86,16 @@
 {
     opus_int   i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
     opus_int32 nSamplesOutDec, LBRR_symbol;
-    opus_int16 samplesOut1_tmp[ 2 ][ MAX_FS_KHZ * MAX_FRAME_LENGTH_MS + 2 ];
-    opus_int16 samplesOut2_tmp[ MAX_API_FS_KHZ * MAX_FRAME_LENGTH_MS ];
+    opus_int16 *samplesOut1_tmp[ 2 ];
+    VARDECL( opus_int16, samplesOut1_tmp_storage );
+    VARDECL( opus_int16, samplesOut2_tmp );
     opus_int32 MS_pred_Q13[ 2 ] = { 0 };
     opus_int16 *resample_out_ptr;
     silk_decoder *psDec = ( silk_decoder * )decState;
     silk_decoder_state *channel_state = psDec->channel_state;
     opus_int has_side;
     opus_int stereo_to_mono;
+    SAVE_STACK;
 
     /**********************************/
     /* Test if first frame in payload */
@@ -132,11 +135,13 @@
                 channel_state[ n ].nb_subfr = 4;
             } else {
                 silk_assert( 0 );
+                RESTORE_STACK;
                 return SILK_DEC_INVALID_FRAME_SIZE;
             }
             fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
             if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
                 silk_assert( 0 );
+                RESTORE_STACK;
                 return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
             }
             ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate );
@@ -153,6 +158,7 @@
 
     if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) {
         ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY;
+        RESTORE_STACK;
         return( ret );
     }
 
@@ -240,6 +246,14 @@
         psDec->channel_state[ 1 ].first_frame_after_reset = 1;
     }
 
+    ALLOC( samplesOut1_tmp_storage,
+           decControl->nChannelsInternal*(
+               channel_state[ 0 ].frame_length + 2 ),
+           opus_int16 );
+    samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage;
+    samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage
+                           + channel_state[ 0 ].frame_length + 2;
+
     if( lostFlag == FLAG_DECODE_NORMAL ) {
         has_side = !decode_only_middle;
     } else {
@@ -285,6 +299,8 @@
     *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) );
 
     /* Set up pointers to temp buffers */
+    ALLOC( samplesOut2_tmp,
+           decControl->nChannelsAPI == 2 ? *nSamplesOut : 0, opus_int16 );
     if( decControl->nChannelsAPI == 2 ) {
         resample_out_ptr = samplesOut2_tmp;
     } else {
@@ -337,6 +353,7 @@
     } else {
        psDec->prev_decode_only_middle = decode_only_middle;
     }
+    RESTORE_STACK;
     return ret;
 }
 
diff --git a/silk/decode_core.c b/silk/decode_core.c
index 2142dd4..0365ffd 100644
--- a/silk/decode_core.c
+++ b/silk/decode_core.c
@@ -30,6 +30,7 @@
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 /**********************************************************/
 /* Core decoder. Performs inverse NSQ operation LTP + LPC */
@@ -43,15 +44,21 @@
 {
     opus_int   i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
     opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ];
-    opus_int16 sLTP[ MAX_FRAME_LENGTH ];
-    opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
+    VARDECL( opus_int16, sLTP );
+    VARDECL( opus_int32, sLTP_Q15 );
     opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10;
     opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14;
-    opus_int32 res_Q14[ MAX_SUB_FRAME_LENGTH ];
-    opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
+    VARDECL( opus_int32, res_Q14 );
+    VARDECL( opus_int32, sLPC_Q14 );
+    SAVE_STACK;
 
     silk_assert( psDec->prev_gain_Q16 != 0 );
 
+    ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 );
+    ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 );
+    ALLOC( res_Q14, psDec->subfr_length, opus_int32 );
+    ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 );
+
     offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ];
 
     if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) {
@@ -227,4 +234,5 @@
 
     /* Save LPC state */
     silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) );
+    RESTORE_STACK;
 }
diff --git a/silk/decode_frame.c b/silk/decode_frame.c
index 9db93d8..3e4a6e2 100644
--- a/silk/decode_frame.c
+++ b/silk/decode_frame.c
@@ -30,6 +30,7 @@
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 #include "PLC.h"
 
 /****************/
@@ -44,12 +45,16 @@
     opus_int                    condCoding                      /* I    The type of conditional coding to use       */
 )
 {
-    silk_decoder_control sDecCtrl;
+    VARDECL( silk_decoder_control, psDecCtrl );
     opus_int         L, mv_len, ret = 0;
-    opus_int         pulses[ MAX_FRAME_LENGTH ];
+    VARDECL( opus_int, pulses );
+    SAVE_STACK;
 
     L = psDec->frame_length;
-    sDecCtrl.LTP_scale_Q14 = 0;
+    ALLOC( psDecCtrl, 1, silk_decoder_control );
+    ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) &
+                   ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int );
+    psDecCtrl->LTP_scale_Q14 = 0;
 
     /* Safety checks */
     silk_assert( L > 0 && L <= MAX_FRAME_LENGTH );
@@ -71,20 +76,17 @@
         /********************************************/
         /* Decode parameters and pulse signal       */
         /********************************************/
-        silk_decode_parameters( psDec, &sDecCtrl, condCoding );
-
-        /* Update length. Sampling frequency may have changed */
-        L = psDec->frame_length;
+        silk_decode_parameters( psDec, psDecCtrl, condCoding );
 
         /********************************************************/
         /* Run inverse NSQ                                      */
         /********************************************************/
-        silk_decode_core( psDec, &sDecCtrl, pOut, pulses );
+        silk_decode_core( psDec, psDecCtrl, pOut, pulses );
 
         /********************************************************/
         /* Update PLC state                                     */
         /********************************************************/
-        silk_PLC( psDec, &sDecCtrl, pOut, 0 );
+        silk_PLC( psDec, psDecCtrl, pOut, 0 );
 
         psDec->lossCnt = 0;
         psDec->prevSignalType = psDec->indices.signalType;
@@ -94,7 +96,7 @@
         psDec->first_frame_after_reset = 0;
     } else {
         /* Handle packet loss by extrapolation */
-        silk_PLC( psDec, &sDecCtrl, pOut, 1 );
+        silk_PLC( psDec, psDecCtrl, pOut, 1 );
     }
 
     /*************************/
@@ -113,13 +115,14 @@
     /************************************************/
     /* Comfort noise generation / estimation        */
     /************************************************/
-    silk_CNG( psDec, &sDecCtrl, pOut, L );
+    silk_CNG( psDec, psDecCtrl, pOut, L );
 
     /* Update some decoder state variables */
-    psDec->lagPrev = sDecCtrl.pitchL[ psDec->nb_subfr - 1 ];
+    psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ];
 
     /* Set output frame length */
     *pN = L;
 
+    RESTORE_STACK;
     return ret;
 }
diff --git a/silk/enc_API.c b/silk/enc_API.c
index c0143fd..ec7915c 100644
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -40,6 +40,14 @@
 #include "main_FLP.h"
 #endif
 
+/***************************************/
+/* Read control structure from encoder */
+/***************************************/
+static opus_int silk_QueryEncoder(                      /* O    Returns error code                              */
+    const void                      *encState,          /* I    State                                           */
+    silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
+);
+
 /****************************************/
 /* Encoder functions                    */
 /****************************************/
@@ -90,7 +98,7 @@
 /***************************************/
 /* Read control structure from encoder */
 /***************************************/
-opus_int silk_QueryEncoder(                             /* O    Returns error code                              */
+static opus_int silk_QueryEncoder(                      /* O    Returns error code                              */
     const void                      *encState,          /* I    State                                           */
     silk_EncControlStruct           *encStatus          /* O    Encoder Status                                  */
 )
diff --git a/silk/fixed/LTP_analysis_filter_FIX.c b/silk/fixed/LTP_analysis_filter_FIX.c
index 155eea8..a8fee55 100644
--- a/silk/fixed/LTP_analysis_filter_FIX.c
+++ b/silk/fixed/LTP_analysis_filter_FIX.c
@@ -33,13 +33,13 @@
 
 void silk_LTP_analysis_filter_FIX(
     opus_int16                      *LTP_res,                               /* O    LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */
-    const opus_int16                *x,                                     /* I    Pointer to input signal with at least max( pitchL ) preceeding samples      */
+    const opus_int16                *x,                                     /* I    Pointer to input signal with at least max( pitchL ) preceding samples       */
     const opus_int16                LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I    LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */
     const opus_int                  pitchL[ MAX_NB_SUBFR ],                 /* I    Pitch lag, one for each subframe                                            */
     const opus_int32                invGains_Q16[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains, one for each subframe                           */
     const opus_int                  subfr_length,                           /* I    Length of each subframe                                                     */
     const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */
-    const opus_int                  pre_length                              /* I    Length of the preceeding samples starting at &x[0] for each subframe        */
+    const opus_int                  pre_length                              /* I    Length of the preceding samples starting at &x[0] for each subframe         */
 )
 {
     const opus_int16 *x_ptr, *x_lag_ptr;
diff --git a/silk/fixed/burg_modified_FIX.c b/silk/fixed/burg_modified_FIX.c
index ecbba03..26a66b1 100644
--- a/silk/fixed/burg_modified_FIX.c
+++ b/silk/fixed/burg_modified_FIX.c
@@ -47,7 +47,7 @@
     opus_int32                  A_Q16[],            /* O    Prediction coefficients (length order)                      */
     const opus_int16            x[],                /* I    Input signal, length: nb_subfr * ( D + subfr_length )       */
     const opus_int32            minInvGain_Q30,     /* I    Inverse of max prediction gain                              */
-    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceeding samples)   */
+    const opus_int              subfr_length,       /* I    Input signal subframe length (incl. D preceding samples)    */
     const opus_int              nb_subfr,           /* I    Number of subframes stacked in x                            */
     const opus_int              D                   /* I    Order                                                       */
 )
@@ -238,7 +238,7 @@
             /* Scale coefficients */
             A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
         }
-        /* Subtract energy of preceeding samples from C0 */
+        /* Subtract energy of preceding samples from C0 */
         if( rshifts > 0 ) {
             for( s = 0; s < nb_subfr; s++ ) {
                 x_ptr = x + s * subfr_length;
diff --git a/silk/fixed/find_pitch_lags_FIX.c b/silk/fixed/find_pitch_lags_FIX.c
index a323411..39c3048 100644
--- a/silk/fixed/find_pitch_lags_FIX.c
+++ b/silk/fixed/find_pitch_lags_FIX.c
@@ -54,7 +54,7 @@
     /******************************************/
     buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
 
-    /* Safty check */
+    /* Safety check */
     silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
 
     x_buf = x - psEnc->sCmn.ltp_mem_length;
@@ -101,7 +101,7 @@
     }
 
     /* Do BWE */
-    silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWITH_EXPANSION, 16 ) );
+    silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );
 
     /*****************************************/
     /* LPC analysis filtering                */
diff --git a/silk/fixed/main_FIX.h b/silk/fixed/main_FIX.h
index 1e60f88..369b31e 100644
--- a/silk/fixed/main_FIX.h
+++ b/silk/fixed/main_FIX.h
@@ -168,17 +168,17 @@
 
 void silk_LTP_analysis_filter_FIX(
     opus_int16                      *LTP_res,                               /* O    LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length )  */
-    const opus_int16                *x,                                     /* I    Pointer to input signal with at least max( pitchL ) preceeding samples      */
+    const opus_int16                *x,                                     /* I    Pointer to input signal with at least max( pitchL ) preceding samples       */
     const opus_int16                LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I    LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe                   */
     const opus_int                  pitchL[ MAX_NB_SUBFR ],                 /* I    Pitch lag, one for each subframe                                            */
     const opus_int32                invGains_Q16[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains, one for each subframe                           */
     const opus_int                  subfr_length,                           /* I    Length of each subframe                                                     */
     const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */
-    const opus_int                  pre_length                              /* I    Length of the preceeding samples starting at &x[0] for each subframe        */
+    const opus_int                  pre_length                              /* I    Length of the preceding samples starting at &x[0] for each subframe         */
 );
 
 /* Calculates residual energies of input subframes where all subframes have LPC_order   */
-/* of preceeding samples                                                                */
+/* of preceding samples                                                                 */
 void silk_residual_energy_FIX(
           opus_int32                nrgs[ MAX_NB_SUBFR ],                   /* O    Residual energy per subframe                                                */
           opus_int                  nrgsQ[ MAX_NB_SUBFR ],                  /* O    Q value per subframe                                                        */
diff --git a/silk/fixed/noise_shape_analysis_FIX.c b/silk/fixed/noise_shape_analysis_FIX.c
index b0e35de..d230e48 100644
--- a/silk/fixed/noise_shape_analysis_FIX.c
+++ b/silk/fixed/noise_shape_analysis_FIX.c
@@ -199,7 +199,7 @@
     /*************************/
     /* Set quantizer offset */
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
-        /* Initally set to 0; may be overruled in process_gains(..) */
+        /* Initially set to 0; may be overruled in process_gains(..) */
         psEnc->sCmn.indices.quantOffsetType = 0;
         psEncCtrl->sparseness_Q8 = 0;
     } else {
diff --git a/silk/fixed/pitch_analysis_core_FIX.c b/silk/fixed/pitch_analysis_core_FIX.c
index bb9166e..d43f444 100644
--- a/silk/fixed/pitch_analysis_core_FIX.c
+++ b/silk/fixed/pitch_analysis_core_FIX.c
@@ -500,7 +500,7 @@
         silk_assert( lag == silk_SAT16( lag ) );
         contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag );
 
-        /* Set up codebook parameters acording to complexity setting and frame length */
+        /* Set up codebook parameters according to complexity setting and frame length */
         if( nb_subfr == PE_MAX_NB_SUBFR ) {
             nb_cbk_search   = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
             cbk_size        = PE_NB_CBKS_STAGE3_MAX;
diff --git a/silk/fixed/residual_energy_FIX.c b/silk/fixed/residual_energy_FIX.c
index 912b16b..f284e51 100644
--- a/silk/fixed/residual_energy_FIX.c
+++ b/silk/fixed/residual_energy_FIX.c
@@ -32,7 +32,7 @@
 #include "main_FIX.h"
 
 /* Calculates residual energies of input subframes where all subframes have LPC_order   */
-/* of preceeding samples                                                                */
+/* of preceding samples                                                                 */
 void silk_residual_energy_FIX(
           opus_int32                nrgs[ MAX_NB_SUBFR ],                   /* O    Residual energy per subframe                                                */
           opus_int                  nrgsQ[ MAX_NB_SUBFR ],                  /* O    Q value per subframe                                                        */
@@ -54,7 +54,7 @@
 
     /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
     for( i = 0; i < nb_subfr >> 1; i++ ) {
-        /* Calculate half frame LPC residual signal including preceeding samples */
+        /* Calculate half frame LPC residual signal including preceding samples */
         silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order );
 
         /* Point to first subframe of the just calculated LPC residual signal */
diff --git a/silk/float/LTP_analysis_filter_FLP.c b/silk/float/LTP_analysis_filter_FLP.c
index 297c813..d3a6a5a 100644
--- a/silk/float/LTP_analysis_filter_FLP.c
+++ b/silk/float/LTP_analysis_filter_FLP.c
@@ -33,13 +33,13 @@
 
 void silk_LTP_analysis_filter_FLP(
     silk_float                      *LTP_res,                           /* O    LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
-    const silk_float                *x,                                 /* I    Input signal, with preceeding samples       */
+    const silk_float                *x,                                 /* I    Input signal, with preceding samples        */
     const silk_float                B[ LTP_ORDER * MAX_NB_SUBFR ],      /* I    LTP coefficients for each subframe          */
     const opus_int                  pitchL[   MAX_NB_SUBFR ],           /* I    Pitch lags                                  */
     const silk_float                invGains[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains                  */
     const opus_int                  subfr_length,                       /* I    Length of each subframe                     */
     const opus_int                  nb_subfr,                           /* I    number of subframes                         */
-    const opus_int                  pre_length                          /* I    Preceeding samples for each subframe        */
+    const opus_int                  pre_length                          /* I    Preceding samples for each subframe         */
 )
 {
     const silk_float *x_ptr, *x_lag_ptr;
diff --git a/silk/float/SigProc_FLP.h b/silk/float/SigProc_FLP.h
index 18e2571..036b46d 100644
--- a/silk/float/SigProc_FLP.h
+++ b/silk/float/SigProc_FLP.h
@@ -109,7 +109,7 @@
     silk_float          A[],                /* O    prediction coefficients (length order)                      */
     const silk_float    x[],                /* I    input signal, length: nb_subfr*(D+L_sub)                    */
     const silk_float    minInvGain,         /* I    minimum inverse prediction gain                             */
-    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceeding samples)   */
+    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceding samples)    */
     const opus_int      nb_subfr,           /* I    number of subframes stacked in x                            */
     const opus_int      D                   /* I    order                                                       */
 );
diff --git a/silk/float/burg_modified_FLP.c b/silk/float/burg_modified_FLP.c
index 0add3a6..31c9b22 100644
--- a/silk/float/burg_modified_FLP.c
+++ b/silk/float/burg_modified_FLP.c
@@ -40,7 +40,7 @@
     silk_float          A[],                /* O    prediction coefficients (length order)                      */
     const silk_float    x[],                /* I    input signal, length: nb_subfr*(D+L_sub)                    */
     const silk_float    minInvGain,         /* I    minimum inverse prediction gain                             */
-    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceeding samples)   */
+    const opus_int      subfr_length,       /* I    input signal subframe length (incl. D preceding samples)    */
     const opus_int      nb_subfr,           /* I    number of subframes stacked in x                            */
     const opus_int      D                   /* I    order                                                       */
 )
@@ -162,7 +162,7 @@
         for( k = 0; k < D; k++ ) {
             A[ k ] = (silk_float)( -Af[ k ] );
         }
-        /* Subtract energy of preceeding samples from C0 */
+        /* Subtract energy of preceding samples from C0 */
         for( s = 0; s < nb_subfr; s++ ) {
             C0 -= silk_energy_FLP( x + s * subfr_length, D );
         }
diff --git a/silk/float/find_pitch_lags_FLP.c b/silk/float/find_pitch_lags_FLP.c
index b3ade8f..00862a6 100644
--- a/silk/float/find_pitch_lags_FLP.c
+++ b/silk/float/find_pitch_lags_FLP.c
@@ -54,7 +54,7 @@
     /******************************************/
     buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
 
-    /* Safty check */
+    /* Safety check */
     silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
 
     x_buf = x - psEnc->sCmn.ltp_mem_length;
@@ -96,7 +96,7 @@
     silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );
 
     /* Bandwidth expansion */
-    silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION );
+    silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION );
 
     /*****************************************/
     /* LPC analysis filtering                */
diff --git a/silk/float/main_FLP.h b/silk/float/main_FLP.h
index 202a7fe..93455d4 100644
--- a/silk/float/main_FLP.h
+++ b/silk/float/main_FLP.h
@@ -164,17 +164,17 @@
 
 void silk_LTP_analysis_filter_FLP(
     silk_float                      *LTP_res,                           /* O    LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
-    const silk_float                *x,                                 /* I    Input signal, with preceeding samples       */
+    const silk_float                *x,                                 /* I    Input signal, with preceding samples        */
     const silk_float                B[ LTP_ORDER * MAX_NB_SUBFR ],      /* I    LTP coefficients for each subframe          */
     const opus_int                  pitchL[   MAX_NB_SUBFR ],           /* I    Pitch lags                                  */
     const silk_float                invGains[ MAX_NB_SUBFR ],           /* I    Inverse quantization gains                  */
     const opus_int                  subfr_length,                       /* I    Length of each subframe                     */
     const opus_int                  nb_subfr,                           /* I    number of subframes                         */
-    const opus_int                  pre_length                          /* I    Preceeding samples for each subframe        */
+    const opus_int                  pre_length                          /* I    Preceding samples for each subframe         */
 );
 
 /* Calculates residual energies of input subframes where all subframes have LPC_order   */
-/* of preceeding samples                                                                */
+/* of preceding samples                                                                 */
 void silk_residual_energy_FLP(
     silk_float                      nrgs[ MAX_NB_SUBFR ],               /* O    Residual energy per subframe                */
     const silk_float                x[],                                /* I    Input signal                                */
diff --git a/silk/float/noise_shape_analysis_FLP.c b/silk/float/noise_shape_analysis_FLP.c
index 1c203b3..33bfd20 100644
--- a/silk/float/noise_shape_analysis_FLP.c
+++ b/silk/float/noise_shape_analysis_FLP.c
@@ -174,7 +174,7 @@
     /*************************/
     /* Set quantizer offset */
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
-        /* Initally set to 0; may be overruled in process_gains(..) */
+        /* Initially set to 0; may be overruled in process_gains(..) */
         psEnc->sCmn.indices.quantOffsetType = 0;
         psEncCtrl->sparseness = 0.0f;
     } else {
diff --git a/silk/float/pitch_analysis_core_FLP.c b/silk/float/pitch_analysis_core_FLP.c
index d23e4ee..fbff90c 100644
--- a/silk/float/pitch_analysis_core_FLP.c
+++ b/silk/float/pitch_analysis_core_FLP.c
@@ -419,7 +419,7 @@
         silk_assert( lag == silk_SAT16( lag ) );
         contour_bias = PE_FLATCONTOUR_BIAS / lag;
 
-        /* Set up cbk parameters acording to complexity setting and frame length */
+        /* Set up cbk parameters according to complexity setting and frame length */
         if( nb_subfr == PE_MAX_NB_SUBFR ) {
             nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
             cbk_size      = PE_NB_CBKS_STAGE3_MAX;
diff --git a/silk/float/prefilter_FLP.c b/silk/float/prefilter_FLP.c
index 95b32da..d6c8439 100644
--- a/silk/float/prefilter_FLP.c
+++ b/silk/float/prefilter_FLP.c
@@ -47,7 +47,7 @@
     opus_int                    length              /* I */
 );
 
-void silk_warped_LPC_analysis_filter_FLP(
+static void silk_warped_LPC_analysis_filter_FLP(
           silk_float                 state[],            /* I/O  State [order + 1]                       */
           silk_float                 res[],              /* O    Residual signal [length]                */
     const silk_float                 coef[],             /* I    Coefficients [order]                    */
diff --git a/silk/float/residual_energy_FLP.c b/silk/float/residual_energy_FLP.c
index 4fa0e67..e65457a 100644
--- a/silk/float/residual_energy_FLP.c
+++ b/silk/float/residual_energy_FLP.c
@@ -87,7 +87,7 @@
 }
 
 /* Calculates residual energies of input subframes where all subframes have LPC_order   */
-/* of preceeding samples                                                                */
+/* of preceding samples                                                                 */
 void silk_residual_energy_FLP(
     silk_float                      nrgs[ MAX_NB_SUBFR ],               /* O    Residual energy per subframe                */
     const silk_float                x[],                                /* I    Input signal                                */
diff --git a/silk/float/wrappers_FLP.c b/silk/float/wrappers_FLP.c
index 5500425..4259e90 100644
--- a/silk/float/wrappers_FLP.c
+++ b/silk/float/wrappers_FLP.c
@@ -155,7 +155,7 @@
 
     /* Convert input to fix */
     for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
-        x_Q3[ i ] = silk_float2int( 8.0 * x[ i ] );
+        x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] );
     }
 
     /* Call NSQ */
diff --git a/silk/resampler_rom.c b/silk/resampler_rom.c
index a09d188..b50af2e 100644
--- a/silk/resampler_rom.c
+++ b/silk/resampler_rom.c
@@ -34,18 +34,10 @@
 
 #include "resampler_private.h"
 
-/* Tables for 2x downsampler */
-const opus_int16 silk_resampler_down2_0 = 9872;
-const opus_int16 silk_resampler_down2_1 = 39809 - 65536;
-
-/* Tables for 2x upsampler, high quality */
-const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 };
-const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 };
-
 /* Matlab code for the notch filter coefficients: */
 /* B = [1, 0.147, 1];  A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */
 /* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */
-const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634,  -7012,   7209,  30474 };
+/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634,  -7012,   7209,  30474 }; */
 
 /* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */
 silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
diff --git a/silk/resampler_rom.h b/silk/resampler_rom.h
index 0ad0686..473b24a 100644
--- a/silk/resampler_rom.h
+++ b/silk/resampler_rom.h
@@ -42,12 +42,12 @@
 #define RESAMPLER_ORDER_FIR_12                  8
 
 /* Tables for 2x downsampler */
-extern const opus_int16 silk_resampler_down2_0;
-extern const opus_int16 silk_resampler_down2_1;
+static const opus_int16 silk_resampler_down2_0 = 9872;
+static const opus_int16 silk_resampler_down2_1 = 39809 - 65536;
 
 /* Tables for 2x upsampler, high quality */
-extern const opus_int16 silk_resampler_up2_hq_0[ 3 ];
-extern const opus_int16 silk_resampler_up2_hq_1[ 3 ];
+static const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 };
+static const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 };
 
 /* Tables with IIR and FIR coefficients for fractional downsamplers */
 extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ];
diff --git a/silk/tables_LTP.c b/silk/tables_LTP.c
index 5522e32..dd1fb55 100644
--- a/silk/tables_LTP.c
+++ b/silk/tables_LTP.c
@@ -35,16 +35,16 @@
        179,     99,      0
 };
 
-const opus_uint8 silk_LTP_gain_iCDF_0[8] = {
+static const opus_uint8 silk_LTP_gain_iCDF_0[8] = {
         71,     56,     43,     30,     21,     12,      6,      0
 };
 
-const opus_uint8 silk_LTP_gain_iCDF_1[16] = {
+static const opus_uint8 silk_LTP_gain_iCDF_1[16] = {
        199,    165,    144,    124,    109,     96,     84,     71,
         61,     51,     42,     32,     23,     15,      8,      0
 };
 
-const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
+static const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
        241,    225,    211,    199,    187,    175,    164,    153,
        142,    132,    123,    114,    105,     96,     88,     80,
         72,     64,     57,     50,     44,     38,     33,     29,
@@ -53,16 +53,16 @@
 
 const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;
 
-const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
+static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
         15,    131,    138,    138,    155,    155,    173,    173
 };
 
-const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = {
+static const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = {
         69,     93,    115,    118,    131,    138,    141,    138,
        150,    150,    155,    150,    155,    160,    166,    160
 };
 
-const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {
+static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {
        131,    128,    134,    141,    141,    141,    145,    145,
        145,    150,    155,    155,    155,    155,    160,    160,
        160,    160,    166,    166,    173,    173,    182,    192,
@@ -81,7 +81,7 @@
     silk_LTP_gain_BITS_Q5_2
 };
 
-const opus_int8 silk_LTP_gain_vq_0[8][5] =
+static const opus_int8 silk_LTP_gain_vq_0[8][5] =
 {
 {
          4,      6,     24,      7,      5
@@ -109,7 +109,7 @@
 }
 };
 
-const opus_int8 silk_LTP_gain_vq_1[16][5] =
+static const opus_int8 silk_LTP_gain_vq_1[16][5] =
 {
 {
         13,     22,     39,     23,     12
@@ -161,7 +161,7 @@
 }
 };
 
-const opus_int8 silk_LTP_gain_vq_2[32][5] =
+static const opus_int8 silk_LTP_gain_vq_2[32][5] =
 {
 {
         -6,     27,     61,     39,      5
diff --git a/silk/tables_NLSF_CB_NB_MB.c b/silk/tables_NLSF_CB_NB_MB.c
index 57bb817..7548052 100644
--- a/silk/tables_NLSF_CB_NB_MB.c
+++ b/silk/tables_NLSF_CB_NB_MB.c
@@ -31,7 +31,7 @@
 
 #include "tables.h"
 
-const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
+static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
         12,     35,     60,     83,    108,    132,    157,    180,
        206,    228,     15,     32,     55,     77,    101,    125,
        151,    175,    201,    225,     19,     42,     66,     89,
@@ -74,7 +74,7 @@
         64,     84,    104,    118,    156,    177,    201,    230
 };
 
-const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
+static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
        212,    178,    148,    129,    108,     96,     85,     82,
         79,     77,     61,     59,     57,     56,     51,     49,
         48,     45,     42,     41,     40,     38,     36,     34,
@@ -85,7 +85,7 @@
         28,     20,     19,     18,     12,     11,      5,      0
 };
 
-const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = {
+static const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = {
         16,      0,      0,      0,      0,     99,     66,     36,
         36,     34,     36,     34,     34,     34,     34,     83,
         69,     36,     52,     34,    116,    102,     70,     68,
@@ -108,7 +108,7 @@
        171,    137,    139,    137,    155,    218,    219,    139
 };
 
-const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = {
        255,    254,    253,    238,     14,      3,      2,      1,
          0,    255,    254,    252,    218,     35,      3,      2,
          1,      0,    255,    254,    250,    208,     59,      4,
@@ -120,7 +120,7 @@
        254,    236,    173,     95,     37,      7,      1,      0
 };
 
-const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = {
        255,    255,    255,    131,      6,    145,    255,    255,
        255,    255,    255,    236,     93,     15,     96,    255,
        255,    255,    255,    255,    194,     83,     25,     71,
@@ -132,13 +132,13 @@
        251,    123,     65,     55,     68,    100,    171,    255
 };
 
-const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = {
+static const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = {
        179,    138,    140,    148,    151,    149,    153,    151,
        163,    116,     67,     82,     59,     92,     72,    100,
         89,     92
 };
 
-const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {
+static const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = {
        250,      3,      6,      3,      3,      3,      4,      3,
          3,      3,    461
 };
diff --git a/silk/tables_NLSF_CB_WB.c b/silk/tables_NLSF_CB_WB.c
index 00b68f7..3d6052e 100644
--- a/silk/tables_NLSF_CB_WB.c
+++ b/silk/tables_NLSF_CB_WB.c
@@ -31,7 +31,7 @@
 
 #include "tables.h"
 
-const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
+static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
          7,     23,     38,     54,     69,     85,    100,    116,
        131,    147,    162,    178,    193,    208,    223,    239,
         13,     25,     41,     55,     69,     83,     98,    112,
@@ -98,7 +98,7 @@
        110,    119,    129,    141,    175,    198,    218,    237
 };
 
-const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
+static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
        225,    204,    201,    184,    183,    175,    158,    154,
        153,    135,    119,    115,    113,    110,    109,     99,
         98,     95,     79,     68,     52,     50,     48,     45,
@@ -109,7 +109,7 @@
         24,     21,     11,      6,      5,      4,      3,      0
 };
 
-const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = {
+static const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = {
          0,      0,      0,      0,      0,      0,      0,      1,
        100,    102,    102,     68,     68,     36,     34,     96,
        164,    107,    158,    185,    180,    185,    139,    102,
@@ -144,7 +144,7 @@
        100,    107,    120,    119,     36,    197,     24,      0
 };
 
-const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = {
        255,    254,    253,    244,     12,      3,      2,      1,
          0,    255,    254,    252,    224,     38,      3,      2,
          1,      0,    255,    254,    251,    209,     57,      4,
@@ -156,7 +156,7 @@
        248,    227,    177,    100,     19,      2,      1,      0
 };
 
-const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = {
+static const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = {
        255,    255,    255,    156,      4,    154,    255,    255,
        255,    255,    255,    227,    102,     15,     92,    255,
        255,    255,    255,    255,    213,     83,     24,     72,
@@ -168,14 +168,14 @@
        166,    116,     76,     55,     53,    125,    255,    255
 };
 
-const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = {
+static const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = {
        175,    148,    160,    176,    178,    173,    174,    164,
        177,    174,    196,    182,    198,    192,    182,     68,
         62,     66,     60,     72,    117,     85,     90,    118,
        136,    151,    142,    160,    142,    155
 };
 
-const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {
+static const opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = {
        100,      3,     40,      3,      3,      3,      5,     14,
         14,     10,     11,      3,      8,      9,      7,      3,
        347
diff --git a/silk/tables_other.c b/silk/tables_other.c
index dedff26..3dc68d4 100644
--- a/silk/tables_other.c
+++ b/silk/tables_other.c
@@ -67,8 +67,8 @@
 const opus_uint8  silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 };
 
 /* Tables for LBRR flags */
-const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 };
-const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 };
+static const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 };
+static const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 };
 const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = {
     silk_LBRR_flags_2_iCDF,
     silk_LBRR_flags_3_iCDF
diff --git a/silk/tuning_parameters.h b/silk/tuning_parameters.h
index 0b0b774..a26de4d 100644
--- a/silk/tuning_parameters.h
+++ b/silk/tuning_parameters.h
@@ -44,7 +44,7 @@
 #define FIND_PITCH_WHITE_NOISE_FRACTION                 1e-3f
 
 /* Bandwidth expansion for whitening filter in pitch analysis */
-#define FIND_PITCH_BANDWITH_EXPANSION                   0.99f
+#define FIND_PITCH_BANDWIDTH_EXPANSION                  0.99f
 
 /*********************/
 /* Linear prediction */
diff --git a/silk_headers.mk b/silk_headers.mk
new file mode 100644
index 0000000..45c6985
--- /dev/null
+++ b/silk_headers.mk
@@ -0,0 +1,26 @@
+SILK_HEAD = \
+silk/debug.h \
+silk/control.h \
+silk/errors.h \
+silk/API.h \
+silk/typedef.h \
+silk/define.h \
+silk/main.h \
+silk/PLC.h \
+silk/structs.h \
+silk/tables.h \
+silk/tuning_parameters.h \
+silk/Inlines.h \
+silk/MacroCount.h \
+silk/MacroDebug.h \
+silk/macros.h \
+silk/pitch_est_defines.h \
+silk/resampler_private.h \
+silk/resampler_rom.h \
+silk/resampler_structs.h \
+silk/SigProc_FIX.h \
+silk/fixed/main_FIX.h \
+silk/fixed/structs_FIX.h \
+silk/float/main_FLP.h \
+silk/float/structs_FLP.h \
+silk/float/SigProc_FLP.h
diff --git a/silk_sources.mk b/silk_sources.mk
new file mode 100644
index 0000000..0de367b
--- /dev/null
+++ b/silk_sources.mk
@@ -0,0 +1,138 @@
+SILK_SOURCES = \
+silk/CNG.c \
+silk/code_signs.c \
+silk/init_decoder.c \
+silk/decode_core.c \
+silk/decode_frame.c \
+silk/decode_parameters.c \
+silk/decode_indices.c \
+silk/decode_pulses.c \
+silk/decoder_set_fs.c \
+silk/dec_API.c \
+silk/enc_API.c \
+silk/encode_indices.c \
+silk/encode_pulses.c \
+silk/gain_quant.c \
+silk/interpolate.c \
+silk/LP_variable_cutoff.c \
+silk/NLSF_decode.c \
+silk/NSQ.c \
+silk/NSQ_del_dec.c \
+silk/PLC.c \
+silk/shell_coder.c \
+silk/tables_gain.c \
+silk/tables_LTP.c \
+silk/tables_NLSF_CB_NB_MB.c \
+silk/tables_NLSF_CB_WB.c \
+silk/tables_other.c \
+silk/tables_pitch_lag.c \
+silk/tables_pulses_per_block.c \
+silk/VAD.c \
+silk/control_audio_bandwidth.c \
+silk/quant_LTP_gains.c \
+silk/VQ_WMat_EC.c \
+silk/HP_variable_cutoff.c \
+silk/NLSF_encode.c \
+silk/NLSF_VQ.c \
+silk/NLSF_unpack.c \
+silk/NLSF_del_dec_quant.c \
+silk/process_NLSFs.c \
+silk/stereo_LR_to_MS.c \
+silk/stereo_MS_to_LR.c \
+silk/check_control_input.c \
+silk/control_SNR.c \
+silk/init_encoder.c \
+silk/control_codec.c \
+silk/A2NLSF.c \
+silk/ana_filt_bank_1.c \
+silk/biquad_alt.c \
+silk/bwexpander_32.c \
+silk/bwexpander.c \
+silk/debug.c \
+silk/decode_pitch.c \
+silk/inner_prod_aligned.c \
+silk/lin2log.c \
+silk/log2lin.c \
+silk/LPC_analysis_filter.c \
+silk/LPC_inv_pred_gain.c \
+silk/table_LSF_cos.c \
+silk/NLSF2A.c \
+silk/NLSF_stabilize.c \
+silk/NLSF_VQ_weights_laroia.c \
+silk/pitch_est_tables.c \
+silk/resampler.c \
+silk/resampler_down2_3.c \
+silk/resampler_down2.c \
+silk/resampler_private_AR2.c \
+silk/resampler_private_down_FIR.c \
+silk/resampler_private_IIR_FIR.c \
+silk/resampler_private_up2_HQ.c \
+silk/resampler_rom.c \
+silk/sigm_Q15.c \
+silk/sort.c \
+silk/sum_sqr_shift.c \
+silk/stereo_decode_pred.c \
+silk/stereo_encode_pred.c \
+silk/stereo_find_predictor.c \
+silk/stereo_quant_pred.c
+
+
+SILK_SOURCES_FIXED = \
+silk/fixed/LTP_analysis_filter_FIX.c \
+silk/fixed/LTP_scale_ctrl_FIX.c \
+silk/fixed/corrMatrix_FIX.c \
+silk/fixed/encode_frame_FIX.c \
+silk/fixed/find_LPC_FIX.c \
+silk/fixed/find_LTP_FIX.c \
+silk/fixed/find_pitch_lags_FIX.c \
+silk/fixed/find_pred_coefs_FIX.c \
+silk/fixed/noise_shape_analysis_FIX.c \
+silk/fixed/prefilter_FIX.c \
+silk/fixed/process_gains_FIX.c \
+silk/fixed/regularize_correlations_FIX.c \
+silk/fixed/residual_energy16_FIX.c \
+silk/fixed/residual_energy_FIX.c \
+silk/fixed/solve_LS_FIX.c \
+silk/fixed/warped_autocorrelation_FIX.c \
+silk/fixed/apply_sine_window_FIX.c \
+silk/fixed/autocorr_FIX.c \
+silk/fixed/burg_modified_FIX.c \
+silk/fixed/k2a_FIX.c \
+silk/fixed/k2a_Q16_FIX.c \
+silk/fixed/pitch_analysis_core_FIX.c \
+silk/fixed/vector_ops_FIX.c \
+silk/fixed/schur64_FIX.c \
+silk/fixed/schur_FIX.c
+
+SILK_SOURCES_FLOAT = \
+silk/float/apply_sine_window_FLP.c \
+silk/float/corrMatrix_FLP.c \
+silk/float/encode_frame_FLP.c \
+silk/float/find_LPC_FLP.c \
+silk/float/find_LTP_FLP.c \
+silk/float/find_pitch_lags_FLP.c \
+silk/float/find_pred_coefs_FLP.c \
+silk/float/LPC_analysis_filter_FLP.c \
+silk/float/LTP_analysis_filter_FLP.c \
+silk/float/LTP_scale_ctrl_FLP.c \
+silk/float/noise_shape_analysis_FLP.c \
+silk/float/prefilter_FLP.c \
+silk/float/process_gains_FLP.c \
+silk/float/regularize_correlations_FLP.c \
+silk/float/residual_energy_FLP.c \
+silk/float/solve_LS_FLP.c \
+silk/float/warped_autocorrelation_FLP.c \
+silk/float/wrappers_FLP.c \
+silk/float/autocorrelation_FLP.c \
+silk/float/burg_modified_FLP.c \
+silk/float/bwexpander_FLP.c \
+silk/float/energy_FLP.c \
+silk/float/inner_product_FLP.c \
+silk/float/k2a_FLP.c \
+silk/float/levinsondurbin_FLP.c \
+silk/float/LPC_inv_pred_gain_FLP.c \
+silk/float/pitch_analysis_core_FLP.c \
+silk/float/scale_copy_vector_FLP.c \
+silk/float/scale_vector_FLP.c \
+silk/float/schur_FLP.c \
+silk/float/sort_FLP.c
diff --git a/src/opus_compare.c b/src/opus_compare.c
index b8a1620..06c67d7 100644
--- a/src/opus_compare.c
+++ b/src/opus_compare.c
@@ -1,3 +1,30 @@
+/* Copyright (c) 2011-2012 Xiph.Org Foundation, Mozilla Corporation
+   Written by Jean-Marc Valin and Timothy B. Terriberry */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index f0188cd..ad5f747 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -30,7 +30,7 @@
 #endif
 
 #ifndef OPUS_BUILD
-#error "OPUS_BUILD _MUST_ be defined to build Opus and you probably want a decent config.h, see README for more details."
+#error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details."
 #endif
 
 #include <stdarg.h>
@@ -64,6 +64,7 @@
    int          prev_mode;
    int          frame_size;
    int          prev_redundancy;
+   int          last_packet_duration;
 
    opus_uint32  rangeFinal;
 };
@@ -257,23 +258,10 @@
       }
    }
 
-   /* For CELT/hybrid PLC of more than 20 ms, do multiple calls */
-   if (data==NULL && frame_size > F20 && mode != MODE_SILK_ONLY)
-   {
-      int nb_samples = 0;
-      do {
-         int ret = opus_decode_frame(st, NULL, 0, pcm, F20, 0);
-         if (ret != F20)
-         {
-            RESTORE_STACK;
-            return OPUS_INTERNAL_ERROR;
-         }
-         pcm += F20*st->channels;
-         nb_samples += F20;
-      } while (nb_samples < frame_size);
-      RESTORE_STACK;
-      return frame_size;
-   }
+   /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do
+      multiple calls */
+   if (data==NULL  && mode != MODE_SILK_ONLY)
+      frame_size = IMIN(frame_size, F20);
    ALLOC(pcm_transition, F5*st->channels, opus_val16);
 
    if (data!=NULL && st->prev_mode > 0 && (
@@ -560,7 +548,7 @@
    int cbr;
    unsigned char ch, toc;
    int framesize;
-   int last_size;
+   opus_int32 last_size;
    const unsigned char *data0 = data;
 
    if (size==NULL)
@@ -586,7 +574,9 @@
       {
          if (len&0x1)
             return OPUS_INVALID_PACKET;
-         size[0] = last_size = len/2;
+         last_size = len/2;
+         /* If last_size doesn't fit in size[0], we'll catch it later */
+         size[0] = (short)last_size;
       }
       break;
    /* Two VBR frames */
@@ -647,7 +637,7 @@
          if (last_size*count!=len)
             return OPUS_INVALID_PACKET;
          for (i=0;i<count-1;i++)
-            size[i] = last_size;
+            size[i] = (short)last_size;
       }
       break;
    }
@@ -675,7 +665,7 @@
          1275. Reject them here.*/
       if (last_size > 1275)
          return OPUS_INVALID_PACKET;
-      size[count-1] = last_size;
+      size[count-1] = (short)last_size;
    }
 
    if (frames)
@@ -712,30 +702,81 @@
    int count, offset;
    unsigned char toc;
    int tot_offset;
+   int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
    /* 48 x 2.5 ms = 120 ms */
    short size[48];
    if (decode_fec<0 || decode_fec>1)
       return OPUS_BAD_ARG;
+   /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
+   if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
+      return OPUS_BAD_ARG;
    if (len==0 || data==NULL)
-      return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0);
-   else if (len<0)
+   {
+      int pcm_count=0;
+      do {
+         int ret;
+         ret = opus_decode_frame(st, NULL, 0, pcm, frame_size-pcm_count, 0);
+         if (ret<0)
+            return ret;
+         pcm += st->channels*ret;
+         pcm_count += ret;
+      } while (pcm_count < frame_size);
+      st->last_packet_duration = pcm_count;
+      return pcm_count;
+   } else if (len<0)
       return OPUS_BAD_ARG;
 
-   tot_offset = 0;
-   st->mode = opus_packet_get_mode(data);
-   st->bandwidth = opus_packet_get_bandwidth(data);
-   st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
-   st->stream_channels = opus_packet_get_nb_channels(data);
+   packet_mode = opus_packet_get_mode(data);
+   packet_bandwidth = opus_packet_get_bandwidth(data);
+   packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
+   packet_stream_channels = opus_packet_get_nb_channels(data);
 
    count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset);
+
+   data += offset;
+
+   if (decode_fec)
+   {
+      int duration_copy;
+      int ret;
+      /* If no FEC can be present, run the PLC (recursive call) */
+      if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY)
+         return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL);
+      /* Otherwise, run the PLC on everything except the size for which we might have FEC */
+      duration_copy = st->last_packet_duration;
+      ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL);
+      if (ret<0)
+      {
+         st->last_packet_duration = duration_copy;
+         return ret;
+      }
+      /* Complete with FEC */
+      st->mode = packet_mode;
+      st->bandwidth = packet_bandwidth;
+      st->frame_size = packet_frame_size;
+      st->stream_channels = packet_stream_channels;
+      ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size),
+            packet_frame_size, 1);
+      if (ret<0)
+         return ret;
+      st->last_packet_duration = frame_size;
+      return frame_size;
+   }
+   tot_offset = 0;
    if (count < 0)
       return count;
 
-   data += offset;
    tot_offset += offset;
 
-   if (count*st->frame_size > frame_size)
+   if (count*packet_frame_size > frame_size)
       return OPUS_BUFFER_TOO_SMALL;
+
+   /* Update the state as the last step to avoid updating it on an invalid packet */
+   st->mode = packet_mode;
+   st->bandwidth = packet_bandwidth;
+   st->frame_size = packet_frame_size;
+   st->stream_channels = packet_stream_channels;
+
    nb_samples=0;
    for (i=0;i<count;i++)
    {
@@ -750,6 +791,7 @@
    }
    if (packet_offset != NULL)
       *packet_offset = tot_offset;
+   st->last_packet_duration = nb_samples;
    return nb_samples;
 }
 
@@ -903,6 +945,12 @@
        st->decode_gain = value;
    }
    break;
+   case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
+   {
+      opus_uint32 *value = va_arg(ap, opus_uint32*);
+      *value = st->last_packet_duration;
+   }
+   break;
    default:
       /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
       ret = OPUS_UNIMPLEMENTED;
@@ -979,8 +1027,8 @@
       return packet[1]&0x3F;
 }
 
-int opus_decoder_get_nb_samples(const OpusDecoder *dec,
-      const unsigned char packet[], opus_int32 len)
+int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,
+      opus_int32 Fs)
 {
    int samples;
    int count = opus_packet_get_nb_frames(packet, len);
@@ -988,10 +1036,16 @@
    if (count<0)
       return count;
 
-   samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs);
+   samples = count*opus_packet_get_samples_per_frame(packet, Fs);
    /* Can't have more than 120 ms */
-   if (samples*25 > dec->Fs*3)
+   if (samples*25 > Fs*3)
       return OPUS_INVALID_PACKET;
    else
       return samples;
 }
+
+int opus_decoder_get_nb_samples(const OpusDecoder *dec,
+      const unsigned char packet[], opus_int32 len)
+{
+   return opus_packet_get_nb_samples(packet, len, dec->Fs);
+}
diff --git a/src/opus_demo.c b/src/opus_demo.c
index 20bebba..09b12a3 100644
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -95,7 +95,7 @@
    }
 }
 
-int silk8_test[][4] = {
+static const int silk8_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960,   1},
@@ -106,7 +106,7 @@
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480,   2}
 };
 
-int silk12_test[][4] = {
+static const int silk12_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960,   1},
@@ -117,7 +117,7 @@
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480,   2}
 };
 
-int silk16_test[][4] = {
+static const int silk16_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960,   1},
@@ -128,21 +128,21 @@
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480,   2}
 };
 
-int hybrid24_test[][4] = {
+static const int hybrid24_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
 };
 
-int hybrid48_test[][4] = {
+static const int hybrid48_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
 };
 
-int celt_test[][4] = {
+static const int celt_test[][4] = {
       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 1},
       {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
       {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND,      960, 1},
@@ -185,7 +185,7 @@
 
 };
 
-int celt_hq_test[][4] = {
+static const int celt_hq_test[][4] = {
       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      960, 2},
       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      480, 2},
       {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND,      240, 2},
@@ -234,7 +234,7 @@
     int random_framesize=0, newsize=0, delayed_celt=0;
     int sweep_max=0, sweep_min=0;
     int random_fec=0;
-    int (*mode_list)[4]=NULL;
+    const int (*mode_list)[4]=NULL;
     int nb_modes_in_list=0;
     int curr_mode=0;
     int curr_mode_count=0;
@@ -684,18 +684,22 @@
         } else {
             int output_samples;
             lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
+            if (lost)
+               opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
+            else
+               output_samples = max_frame_size;
             if( count >= use_inbandfec ) {
                 /* delay by one packet when using in-band FEC */
                 if( use_inbandfec  ) {
                     if( lost_prev ) {
                         /* attempt to decode with in-band FEC from next packet */
-                        output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 1);
+                        output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
                     } else {
                         /* regular decode */
-                        output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, max_frame_size, 0);
+                        output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
                     }
                 } else {
-                    output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, max_frame_size, 0);
+                    output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
                 }
                 if (output_samples>0)
                 {
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index b77e48e..aae3125 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -291,7 +291,7 @@
 }
 
 #ifndef FIXED_POINT
-void silk_biquad_float(
+static void silk_biquad_float(
     const opus_val16      *in,            /* I:    Input signal                   */
     const opus_int32      *B_Q28,         /* I:    MA coefficients [3]            */
     const opus_int32      *A_Q28,         /* I:    AR coefficients [2]            */
@@ -458,20 +458,20 @@
     int prefill=0;
     int start_band = 0;
     int redundancy = 0;
-    int redundancy_bytes = 0;
+    int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
     int celt_to_silk = 0;
     VARDECL(opus_val16, pcm_buf);
     int nb_compr_bytes;
     int to_celt = 0;
     opus_uint32 redundant_rng = 0;
     int cutoff_Hz, hp_freq_smth1;
-    int voice_est;
+    int voice_est; /* Probability of voice in Q7 */
     opus_int32 equiv_rate;
     int delay_compensation;
     int frame_rate;
-    opus_int32 max_rate;
+    opus_int32 max_rate; /* Max bitrate we're allowed to use */
     int curr_bandwidth;
-    opus_int32 max_data_bytes;
+    opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */
     VARDECL(opus_val16, tmp_prefill);
 
     ALLOC_STACK;
@@ -652,6 +652,7 @@
             }
         }
     }
+    /* For the first frame at a new SILK bandwidth */
     if (st->silk_bw_switch)
     {
        redundancy = 1;
@@ -659,6 +660,15 @@
        st->silk_bw_switch = 0;
     }
 
+    if (redundancy)
+    {
+       /* Fair share of the max size allowed */
+       redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));
+       /* For VBR, target the actual bitrate (subject to the limit above) */
+       if (st->use_vbr)
+          redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);
+    }
+
     if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
     {
         silk_EncControlStruct dummy;
@@ -823,7 +833,7 @@
         st->mode = MODE_SILK_ONLY;
 
     /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
-    bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
+    bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
 
     data += 1;
 
@@ -929,7 +939,7 @@
         st->silk_mode.useCBR = !st->use_vbr;
 
         /* Call SILK encoder for the low band */
-        nBytes = IMIN(1275, max_data_bytes-1);
+        nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
 
         st->silk_mode.maxBits = nBytes*8;
         /* Only allow up to 90% of the bits for hybrid mode*/
@@ -941,8 +951,6 @@
            /* Reduce the initial target to make it easier to reach the CBR rate */
            st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
         }
-        if (redundancy)
-           st->silk_mode.maxBits -= st->silk_mode.maxBits/(1 + frame_size/(st->Fs/200));
 
         if (prefill)
         {
@@ -990,6 +998,7 @@
         }
 
         st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
+        /* FIXME: How do we allocate the redundancy for CBR? */
         if (st->silk_mode.opusCanSwitch)
         {
            redundancy = 1;
@@ -1047,7 +1056,7 @@
                 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
                 celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
                 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
-                nb_compr_bytes = max_data_bytes-1;
+                nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
             } else {
                 nb_compr_bytes = bytes_target;
             }
@@ -1119,8 +1128,10 @@
     }
 
     if (!redundancy)
+    {
        st->silk_bw_switch = 0;
-
+       redundancy_bytes = 0;
+    }
     if (st->mode != MODE_CELT_ONLY)start_band=17;
 
     if (st->mode == MODE_SILK_ONLY)
diff --git a/src/opus_multistream.c b/src/opus_multistream.c
index 955dc81..a7f25a5 100644
--- a/src/opus_multistream.c
+++ b/src/opus_multistream.c
@@ -159,7 +159,7 @@
 {
    int coupled_size;
    int mono_size;
-   int i;
+   int i, ret;
    char *ptr;
 
    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
@@ -180,12 +180,14 @@
 
    for (i=0;i<st->layout.nb_coupled_streams;i++)
    {
-      opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
+      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
+      if(ret!=OPUS_OK)return ret;
       ptr += align(coupled_size);
    }
    for (;i<st->layout.nb_streams;i++)
    {
-      opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
+      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
+      if(ret!=OPUS_OK)return ret;
       ptr += align(mono_size);
    }
    return OPUS_OK;
@@ -202,7 +204,15 @@
 )
 {
    int ret;
-   OpusMSEncoder *st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
+   OpusMSEncoder *st;
+   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
+       (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
+   {
+      if (error)
+         *error = OPUS_BAD_ARG;
+      return NULL;
+   }
+   st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
    if (st==NULL)
    {
       if (error)
@@ -647,7 +657,15 @@
 )
 {
    int ret;
-   OpusMSDecoder *st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
+   OpusMSDecoder *st;
+   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
+       (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
+   {
+      if (error)
+         *error = OPUS_BAD_ARG;
+      return NULL;
+   }
+   st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
    if (st==NULL)
    {
       if (error)
@@ -663,8 +681,6 @@
       st = NULL;
    }
    return st;
-
-
 }
 
 typedef void (*opus_copy_channel_out_func)(
@@ -908,6 +924,8 @@
    {
        case OPUS_GET_BANDWIDTH_REQUEST:
        case OPUS_GET_SAMPLE_RATE_REQUEST:
+       case OPUS_GET_GAIN_REQUEST:
+       case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
        {
           OpusDecoder *dec;
           /* For int32* GET params, just query the first stream */
diff --git a/tests/run_vectors.sh b/tests/run_vectors.sh
index 3e021af..1cc445d 100755
--- a/tests/run_vectors.sh
+++ b/tests/run_vectors.sh
@@ -1,5 +1,38 @@
 #!/bin/sh
 
+# Copyright (c) 2011-2012 Jean-Marc Valin
+#
+#  This file is extracted from RFC6716. Please see that RFC for additional
+#  information.
+#
+#  Redistribution and use in source and binary forms, with or without
+#  modification, are permitted provided that the following conditions
+#  are met:
+#
+#  - Redistributions of source code must retain the above copyright
+#  notice, this list of conditions and the following disclaimer.
+#
+#  - Redistributions in binary form must reproduce the above copyright
+#  notice, this list of conditions and the following disclaimer in the
+#  documentation and/or other materials provided with the distribution.
+#
+#  - Neither the name of Internet Society, IETF or IETF Trust, nor the
+#  names of specific contributors, may be used to endorse or promote
+#  products derived from this software without specific prior written
+#  permission.
+#
+#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+#  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 rm logs_mono.txt
 rm logs_stereo.txt
 
diff --git a/tests/test_opus_api.c b/tests/test_opus_api.c
index b5348c3..c2d7e10 100644
--- a/tests/test_opus_api.c
+++ b/tests/test_opus_api.c
@@ -126,6 +126,9 @@
          dec = opus_decoder_create(fs, c, &err);
          if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
          cfgs++;
+         dec = opus_decoder_create(fs, c, 0);
+         if(dec!=NULL)test_failed();
+         cfgs++;
          dec=malloc(opus_decoder_get_size(2));
          if(dec==NULL)test_failed();
          err = opus_decoder_init(dec,fs,c);
@@ -224,12 +227,19 @@
    VG_UNDEF(packet,sizeof(packet));
    packet[0]=0;
    if(opus_decoder_get_nb_samples(dec,packet,1)!=480)test_failed();
-   cfgs++;
+   if(opus_packet_get_nb_samples(packet,1,48000)!=480)test_failed();
+   if(opus_packet_get_nb_samples(packet,1,96000)!=960)test_failed();
+   if(opus_packet_get_nb_samples(packet,1,32000)!=320)test_failed();
+   if(opus_packet_get_nb_samples(packet,1,8000)!=80)test_failed();
+   packet[0]=3;
+   if(opus_packet_get_nb_samples(packet,1,24000)!=OPUS_INVALID_PACKET)test_failed();
    packet[0]=(63<<2)|3;
    packet[1]=63;
+   if(opus_packet_get_nb_samples(packet,0,24000)!=OPUS_BAD_ARG)test_failed();
+   if(opus_packet_get_nb_samples(packet,2,48000)!=OPUS_INVALID_PACKET)test_failed();
    if(opus_decoder_get_nb_samples(dec,packet,2)!=OPUS_INVALID_PACKET)test_failed();
-   fprintf(stdout,"    opus_decoder_get_nb_samples() ................ OK.\n");
-   cfgs++;
+   fprintf(stdout,"    opus_{packet,decoder}_get_nb_samples() ....... OK.\n");
+   cfgs+=9;
 
    if(OPUS_BAD_ARG!=opus_packet_get_nb_frames(packet,0))test_failed();
    for(i=0;i<256;i++) {
@@ -366,6 +376,9 @@
          dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, &err);
          if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
          cfgs++;
+         dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, 0);
+         if(dec!=NULL)test_failed();
+         cfgs++;
          dec=malloc(opus_multistream_decoder_get_size(1,1));
          if(dec==NULL)test_failed();
          err = opus_multistream_decoder_init(dec,fs,c,1,c-1, mapping);
@@ -375,116 +388,128 @@
       }
    }
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err==OPUS_OK || dec!=NULL)test_failed();
-   cfgs++;
+   for(c=0;c<2;c++)
+   {
+      int *ret_err;
+      ret_err = c?0:&err;
 
-   VG_UNDEF(&err,sizeof(err));
-   mapping[0]=mapping[1]=0;
-   dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_OK || dec==NULL)test_failed();
-   cfgs++;
-   opus_multistream_decoder_destroy(dec);
-   cfgs++;
+      mapping[0]=0;
+      mapping[1]=1;
+      for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char));
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_OK || dec==NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping);
-   if(err!=OPUS_BAD_ARG)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      mapping[0]=mapping[1]=0;
+      dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+      cfgs++;
+      opus_multistream_decoder_destroy(dec);
+      cfgs++;
 
-   err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping);
-   if(err!=OPUS_BAD_ARG)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+      cfgs++;
 
-   opus_multistream_decoder_destroy(dec);
-   cfgs++;
+      err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping);
+      if(err!=OPUS_BAD_ARG)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_OK || dec==NULL)test_failed();
-   cfgs++;
-   opus_multistream_decoder_destroy(dec);
-   cfgs++;
+      err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping);
+      if(err!=OPUS_BAD_ARG)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      opus_multistream_decoder_destroy(dec);
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+      cfgs++;
+      opus_multistream_decoder_destroy(dec);
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   mapping[0]=255;
-   mapping[1]=1;
-   mapping[2]=2;
-   dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   VG_UNDEF(&err,sizeof(err));
-   mapping[0]=0;
-   mapping[1]=0;
-   mapping[2]=0;
-   dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, &err);
-   VG_CHECK(&err,sizeof(err));
-   if(err!=OPUS_OK || dec==NULL)test_failed();
-   cfgs++;
-   opus_multistream_decoder_destroy(dec);
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
 
-   mapping[0]=0;
-   mapping[1]=255;
-   mapping[2]=1;
-   mapping[3]=2;
-   mapping[4]=3;
-   dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, 0);
-   if(dec!=NULL)test_failed();
-   cfgs++;
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      mapping[0]=255;
+      mapping[1]=1;
+      mapping[2]=2;
+      dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
+
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      mapping[0]=0;
+      mapping[1]=0;
+      mapping[2]=0;
+      dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed();
+      cfgs++;
+      opus_multistream_decoder_destroy(dec);
+      cfgs++;
+
+      VG_UNDEF(ret_err,sizeof(*ret_err));
+      mapping[0]=0;
+      mapping[1]=255;
+      mapping[2]=1;
+      mapping[3]=2;
+      mapping[4]=3;
+      dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, ret_err);
+      if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));}
+      if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed();
+      cfgs++;
+   }
 
    VG_UNDEF(&err,sizeof(err));
    mapping[0]=0;
@@ -1061,6 +1086,9 @@
          enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, &err);
          if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed();
          cfgs++;
+         enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, 0);
+         if(enc!=NULL)test_failed();
+         cfgs++;
          opus_encoder_destroy(enc);
          enc=malloc(opus_encoder_get_size(2));
          if(enc==NULL)test_failed();
@@ -1538,7 +1566,7 @@
 #ifdef MALLOC_FAIL
 /* GLIBC 2.14 declares __malloc_hook as deprecated, generating a warning
  * under GCC. However, this is the cleanest way to test malloc failure
- * handling in our codebase, and the lack of thread saftey isn't an
+ * handling in our codebase, and the lack of thread safety isn't an
  * issue here. We therefore disable the warning for this function.
  */
 #if OPUS_GNUC_PREREQ(4,6)
diff --git a/tests/test_opus_decode.c b/tests/test_opus_decode.c
index 2c6a872..e2c04c2 100644
--- a/tests/test_opus_decode.c
+++ b/tests/test_opus_decode.c
@@ -38,13 +38,15 @@
 #include <time.h>
 #if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
 #include <unistd.h>
+#else
+#include <process.h>
+#define getpid _getpid
 #endif
 #include "opus.h"
 #include "test_opus_common.h"
 
 #define MAX_PACKET (1500)
 #define MAX_FRAME_SAMP (5760)
-extern int jackpot;
 
 int test_decoder_code0(int no_fuzz)
 {
@@ -102,22 +104,27 @@
       int factor=48000/fsv[t>>1];
       for(fec=0;fec<2;fec++)
       {
+         int dur;
          /*Test PLC on a fresh decoder*/
-         out_samples = opus_decode(dec[t], 0, 0, outbuf, MAX_FRAME_SAMP, fec);
+         out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
+         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+         if(dur!=120/factor)test_failed();
 
          /*Test null pointer input*/
-         out_samples = opus_decode(dec[t], 0, -1, outbuf, MAX_FRAME_SAMP, fec);
+         out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
-         out_samples = opus_decode(dec[t], 0, 1, outbuf, MAX_FRAME_SAMP, fec);
+         out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
-         out_samples = opus_decode(dec[t], 0, 10, outbuf, MAX_FRAME_SAMP, fec);
+         out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
-         out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, MAX_FRAME_SAMP, fec);
+         out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
+         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+         if(dur!=120/factor)test_failed();
 
          /*Zero lengths*/
-         out_samples = opus_decode(dec[t], packet, 0, outbuf, MAX_FRAME_SAMP, fec);
+         out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
 
          /*Zero buffer*/
@@ -149,6 +156,7 @@
    /*Count code 0 tests*/
    for(i=0;i<64;i++)
    {
+      int dur;
       int j,expected[5*2];
       packet[0]=i<<2;
       packet[1]=255;
@@ -168,6 +176,8 @@
          {
             out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
             if(out_samples!=expected[t])test_failed();
+            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+            if(dur!=out_samples)test_failed();
             opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
             if(t==0)dec_final_range2=dec_final_range1;
             else if(dec_final_range1!=dec_final_range2)test_failed();
@@ -179,8 +189,10 @@
          /* The PLC is run for 6 frames in order to get better PLC coverage. */
          for(j=0;j<6;j++)
          {
-            out_samples = opus_decode(dec[t], 0, 0, outbuf, MAX_FRAME_SAMP, 0);
+            out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
             if(out_samples!=expected[t])test_failed();
+            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+            if(dur!=out_samples)test_failed();
          }
          /* Run the PLC once at 2.5ms, as a simulation of someone trying to
             do small drift corrections. */
@@ -188,6 +200,8 @@
          {
             out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
             if(out_samples!=120/factor)test_failed();
+            if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+            if(dur!=out_samples)test_failed();
          }
          out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
          if(out_samples>0)test_failed();
@@ -289,17 +303,20 @@
       for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
       for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
       memcpy(decbak,dec[0],decsize);
-      if(opus_decode(decbak, packet, plen+1, outbuf, MAX_FRAME_SAMP, 1)!=expected[0])test_failed();
+      if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
       memcpy(decbak,dec[0],decsize);
       if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
       memcpy(decbak,dec[0],decsize);
       if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
       for(t=0;t<5*2;t++)
       {
+         int dur;
          out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
          if(out_samples!=expected[t])test_failed();
          if(t==0)dec_final_range2=dec_final_range1;
          else if(dec_final_range1!=dec_final_range2)test_failed();
+         if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
+         if(dur!=out_samples)test_failed();
       }
    }
    fprintf(stdout,"  dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
diff --git a/tests/test_opus_encode.c b/tests/test_opus_encode.c
index ad63453..b80def3 100644
--- a/tests/test_opus_encode.c
+++ b/tests/test_opus_encode.c
@@ -38,6 +38,9 @@
 #include <time.h>
 #if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
 #include <unistd.h>
+#else
+#include <process.h>
+#define getpid _getpid
 #endif
 #include "opus_multistream.h"
 #include "opus.h"
@@ -141,11 +144,44 @@
    enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err);
    if(err != OPUS_OK || enc==NULL)test_failed();
 
+   for(i=0;i<2;i++)
+   {
+      int *ret_err;
+      ret_err = i?0:&err;
+      MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_UNIMPLEMENTED, ret_err);
+      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+      MSenc = opus_multistream_encoder_create(8000, 0, 1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+      MSenc = opus_multistream_encoder_create(44100, 2, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+      MSenc = opus_multistream_encoder_create(8000, 2, 2, 3, mapping, OPUS_APPLICATION_VOIP, ret_err);
+      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+      MSenc = opus_multistream_encoder_create(8000, 2, -1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+
+      MSenc = opus_multistream_encoder_create(8000, 256, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
+      if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
+   }
+
    MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_APPLICATION_AUDIO, &err);
    if(err != OPUS_OK || MSenc==NULL)test_failed();
 
+   /*Some multistream encoder API tests*/
    if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed();
    if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_LSB_DEPTH(&i))!=OPUS_OK)test_failed();
+   if(i<16)test_failed();
+
+   {
+      OpusEncoder *tmp_enc;
+      if(opus_multistream_encoder_ctl(MSenc,  OPUS_MULTISTREAM_GET_ENCODER_STATE(1,&tmp_enc))!=OPUS_OK)test_failed();
+      if(opus_encoder_ctl(tmp_enc, OPUS_GET_LSB_DEPTH(&j))!=OPUS_OK)test_failed();
+      if(i!=j)test_failed();
+      if(opus_multistream_encoder_ctl(MSenc,  OPUS_MULTISTREAM_GET_ENCODER_STATE(2,&tmp_enc))!=OPUS_BAD_ARG)test_failed();
+   }
 
    dec = opus_decoder_create(48000, 2, &err);
    if(err != OPUS_OK || dec==NULL)test_failed();
@@ -233,7 +269,7 @@
             if(opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();
             if(enc_final_range!=dec_final_range)test_failed();
             /*LBRR decode*/
-            out_samples = opus_decode(dec_err[0], packet, len, out2buf, MAX_FRAME_SAMP, (fast_rand()&3)!=0);
+            out_samples = opus_decode(dec_err[0], packet, len, out2buf, frame_size, (fast_rand()&3)!=0);
             if(out_samples!=frame_size)test_failed();
             out_samples = opus_decode(dec_err[1], packet, (fast_rand()&3)==0?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&7)!=0);
             if(out_samples<120)test_failed();
@@ -281,8 +317,8 @@
             if(enc_final_range!=dec_final_range)test_failed();
             /*LBRR decode*/
             loss=(fast_rand()&63)==0;
-            out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&3)!=0);
-            if(loss?out_samples<120:out_samples!=(frame_size*6))test_failed();
+            out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, frame_size*6, (fast_rand()&3)!=0);
+            if(out_samples!=(frame_size*6))test_failed();
             i+=frame_size;
             count++;
          }while(i<(SSAMPLES/12-MAX_FRAME_SAMP));
diff --git a/version.mk b/version.mk
new file mode 100644
index 0000000..ef30573
--- /dev/null
+++ b/version.mk
@@ -0,0 +1,2 @@
+# static version string; update manually every release.
+OPUS_VERSION = "1.0.2"
diff --git a/win32/config.h b/win32/config.h
index 6d32620..8450d23 100644
--- a/win32/config.h
+++ b/win32/config.h
@@ -1,10 +1,36 @@
+/***********************************************************************
+Copyright (c) 2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
 #ifndef CONFIG_H
 #define CONFIG_H
 
 #define CELT_BUILD            1
 
 #define inline __inline
-#define getpid _getpid
 
 #define USE_ALLOCA            1