Opus 1.2.1

Change-Id: I551f1de5c5e121ac1275334e67c7e0f96ab18114

Test: - verified builds for arm*/mips*/x86*
      - checked functionality using an emulator and stagefright
diff --git a/Android.bp b/Android.bp
index b4a8922..4fa2699 100644
--- a/Android.bp
+++ b/Android.bp
@@ -87,6 +87,7 @@
         "silk/lin2log.c",
         "silk/log2lin.c",
         "silk/LPC_analysis_filter.c",
+        "silk/LPC_fit.c",
         "silk/LPC_inv_pred_gain.c",
         "silk/table_LSF_cos.c",
         "silk/NLSF2A.c",
@@ -119,12 +120,10 @@
         "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",
@@ -149,8 +148,6 @@
         "src/analysis.c",
         "src/mlp.c",
         "src/mlp_data.c",
-
-        "src/repacketizer_demo.c",
     ],
 
     cflags: [
@@ -188,6 +185,9 @@
                 // supported on target platform.
                 // CELT_SOURCES_ARM_ASM
                 "celt/arm/celt_pitch_xcorr_arm_gnu.s",
+
+                // CELT_AM_SOURCES_ARM_ASM
+                "celt/arm/armopts_gnu.s",
             ],
 
             cflags: [
@@ -197,6 +197,7 @@
                 "-DOPUS_ARM_INLINE_EDSP",
                 "-DOPUS_ARM_MAY_HAVE_MEDIA",
                 "-DOPUS_ARM_INLINE_MEDIA",
+                "-DOPUS_ARM_MAY_HAVE_NEON",
                 "-DOPUS_HAVE_RTCD",
             ],
 
@@ -207,10 +208,17 @@
                 srcs: [
                     // CELT_SOURCES_ARM_NEON_INTR
                     "celt/arm/celt_neon_intr.c",
+                    "celt/arm/pitch_neon_intr.c",
 
                     // SILK_SOURCES_ARM_NEON_INTR,
                     "silk/arm/arm_silk_map.c",
+                    "silk/arm/biquad_alt_neon_intr.c",
+                    "silk/arm/LPC_inv_pred_gain_neon_intr.c",
+                    "silk/arm/NSQ_del_dec_neon_intr.c",
                     "silk/arm/NSQ_neon.c",
+
+                    // SILK_SOURCES_FIXED_ARM_NEON_INTR,
+                    "silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c",
                 ],
 
                 cflags: [
@@ -233,6 +241,7 @@
 
                     // CELT_SOURCES_SSE2
                     "celt/x86/pitch_sse2.c",
+                    "celt/x86/vq_sse2.c",
                 ],
 
                 cflags: [
@@ -259,7 +268,6 @@
                     // SILK_SOURCES_FIXED_SSE4_1
                     "silk/fixed/x86/vector_ops_FIX_sse.c",
                     "silk/fixed/x86/burg_modified_FIX_sse.c",
-                    "silk/fixed/x86/prefilter_FIX_sse.c",
                 ],
 
                 cflags: [
@@ -305,7 +313,6 @@
                     // SILK_SOURCES_FIXED_SSE4_1
                     "silk/fixed/x86/vector_ops_FIX_sse.c",
                     "silk/fixed/x86/burg_modified_FIX_sse.c",
-                    "silk/fixed/x86/prefilter_FIX_sse.c",
                 ],
 
                 cflags: [
diff --git a/Makefile.am b/Makefile.am
index 7a69114..5b57b33 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,6 +21,9 @@
 if HAVE_SSE4_1
 SILK_SOURCES += $(SILK_SOURCES_SSE4_1) $(SILK_SOURCES_FIXED_SSE4_1)
 endif
+if HAVE_ARM_NEON_INTR
+SILK_SOURCES += $(SILK_SOURCES_FIXED_ARM_NEON_INTR)
+endif
 else
 SILK_SOURCES += $(SILK_SOURCES_FLOAT)
 if HAVE_SSE4_1
@@ -84,9 +87,36 @@
 noinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD)
 
 if EXTRA_PROGRAMS
-noinst_PROGRAMS = opus_demo repacketizer_demo opus_compare tests/test_opus_api tests/test_opus_encode tests/test_opus_decode tests/test_opus_padding celt/tests/test_unit_cwrs32 celt/tests/test_unit_dft celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_mathops celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_types
+noinst_PROGRAMS = celt/tests/test_unit_cwrs32 \
+                  celt/tests/test_unit_dft \
+                  celt/tests/test_unit_entropy \
+                  celt/tests/test_unit_laplace \
+                  celt/tests/test_unit_mathops \
+                  celt/tests/test_unit_mdct \
+                  celt/tests/test_unit_rotation \
+                  celt/tests/test_unit_types \
+                  opus_compare \
+                  opus_demo \
+                  repacketizer_demo \
+                  silk/tests/test_unit_LPC_inv_pred_gain \
+                  tests/test_opus_api \
+                  tests/test_opus_decode \
+                  tests/test_opus_encode \
+                  tests/test_opus_padding
 
-TESTS = celt/tests/test_unit_types celt/tests/test_unit_mathops celt/tests/test_unit_entropy celt/tests/test_unit_laplace celt/tests/test_unit_dft celt/tests/test_unit_mdct celt/tests/test_unit_rotation celt/tests/test_unit_cwrs32 tests/test_opus_api tests/test_opus_decode tests/test_opus_encode tests/test_opus_padding
+TESTS = celt/tests/test_unit_cwrs32 \
+        celt/tests/test_unit_dft \
+        celt/tests/test_unit_entropy \
+        celt/tests/test_unit_laplace \
+        celt/tests/test_unit_mathops \
+        celt/tests/test_unit_mdct \
+        celt/tests/test_unit_rotation \
+        celt/tests/test_unit_types \
+        silk/tests/test_unit_LPC_inv_pred_gain \
+        tests/test_opus_api \
+        tests/test_opus_decode \
+        tests/test_opus_encode \
+        tests/test_opus_padding
 
 opus_demo_SOURCES = src/opus_demo.c
 
@@ -102,7 +132,7 @@
 tests_test_opus_api_SOURCES = tests/test_opus_api.c tests/test_opus_common.h
 tests_test_opus_api_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
 
-tests_test_opus_encode_SOURCES = tests/test_opus_encode.c tests/test_opus_common.h
+tests_test_opus_encode_SOURCES = tests/test_opus_encode.c tests/opus_encode_regressions.c tests/test_opus_common.h
 tests_test_opus_encode_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
 
 tests_test_opus_decode_SOURCES = tests/test_opus_decode.c tests/test_opus_common.h
@@ -111,11 +141,20 @@
 tests_test_opus_padding_SOURCES = tests/test_opus_padding.c tests/test_opus_common.h
 tests_test_opus_padding_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
 
+CELT_OBJ = $(CELT_SOURCES:.c=.lo)
+SILK_OBJ = $(SILK_SOURCES:.c=.lo)
+
+silk_tests_test_unit_LPC_inv_pred_gain_SOURCES = silk/tests/test_unit_LPC_inv_pred_gain.c
+silk_tests_test_unit_LPC_inv_pred_gain_LDADD = $(SILK_OBJ) $(CELT_OBJ) $(NE10_LIBS) $(LIBM)
+if OPUS_ARM_EXTERNAL_ASM
+silk_tests_test_unit_LPC_inv_pred_gain_LDADD += libarmasm.la
+endif
+
 celt_tests_test_unit_cwrs32_SOURCES = celt/tests/test_unit_cwrs32.c
 celt_tests_test_unit_cwrs32_LDADD = $(LIBM)
 
 celt_tests_test_unit_dft_SOURCES = celt/tests/test_unit_dft.c
-celt_tests_test_unit_dft_LDADD = $(NE10_LIBS) $(LIBM)
+celt_tests_test_unit_dft_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM)
 if OPUS_ARM_EXTERNAL_ASM
 celt_tests_test_unit_dft_LDADD += libarmasm.la
 endif
@@ -127,19 +166,19 @@
 celt_tests_test_unit_laplace_LDADD = $(LIBM)
 
 celt_tests_test_unit_mathops_SOURCES = celt/tests/test_unit_mathops.c
-celt_tests_test_unit_mathops_LDADD = $(NE10_LIBS) $(LIBM)
+celt_tests_test_unit_mathops_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM)
 if OPUS_ARM_EXTERNAL_ASM
 celt_tests_test_unit_mathops_LDADD += libarmasm.la
 endif
 
 celt_tests_test_unit_mdct_SOURCES = celt/tests/test_unit_mdct.c
-celt_tests_test_unit_mdct_LDADD = $(NE10_LIBS) $(LIBM)
+celt_tests_test_unit_mdct_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM)
 if OPUS_ARM_EXTERNAL_ASM
 celt_tests_test_unit_mdct_LDADD += libarmasm.la
 endif
 
 celt_tests_test_unit_rotation_SOURCES = celt/tests/test_unit_rotation.c
-celt_tests_test_unit_rotation_LDADD = $(NE10_LIBS) $(LIBM)
+celt_tests_test_unit_rotation_LDADD = $(CELT_OBJ) $(NE10_LIBS) $(LIBM)
 if OPUS_ARM_EXTERNAL_ASM
 celt_tests_test_unit_rotation_LDADD += libarmasm.la
 endif
@@ -157,8 +196,7 @@
 endif
 endif
 
-EXTRA_DIST = version.mk \
-             opus.pc.in \
+EXTRA_DIST = opus.pc.in \
              opus-uninstalled.pc.in \
              opus.m4 \
              Makefile.mips \
@@ -166,25 +204,18 @@
              tests/run_vectors.sh \
              celt/arm/arm2gnu.pl \
              celt/arm/celt_pitch_xcorr_arm.s \
-             win32/VS2015/silk_float.vcxproj \
-             win32/VS2015/celt.vcxproj.filters \
              win32/VS2015/opus.vcxproj \
-             win32/VS2015/silk_common.vcxproj.filters \
-             win32/VS2015/silk_float.vcxproj.filters \
              win32/VS2015/test_opus_encode.vcxproj.filters \
-             win32/VS2015/silk_common.vcxproj \
              win32/VS2015/test_opus_encode.vcxproj \
              win32/VS2015/opus_demo.vcxproj \
              win32/VS2015/test_opus_api.vcxproj.filters \
              win32/VS2015/test_opus_api.vcxproj \
              win32/VS2015/test_opus_decode.vcxproj.filters \
-             win32/VS2015/silk_fixed.vcxproj.filters \
              win32/VS2015/opus_demo.vcxproj.filters \
-             win32/VS2015/silk_fixed.vcxproj \
              win32/VS2015/opus.vcxproj.filters \
              win32/VS2015/test_opus_decode.vcxproj \
-             win32/VS2015/celt.vcxproj \
              win32/VS2015/opus.sln \
+             win32/VS2015/common.props \
              win32/genversion.bat \
              win32/config.h
 
@@ -276,27 +307,30 @@
 OPT_UNIT_TEST_OBJ = $(celt_tests_test_unit_mathops_SOURCES:.c=.o) \
                     $(celt_tests_test_unit_rotation_SOURCES:.c=.o) \
                     $(celt_tests_test_unit_mdct_SOURCES:.c=.o) \
-                    $(celt_tests_test_unit_dft_SOURCES:.c=.o)
+                    $(celt_tests_test_unit_dft_SOURCES:.c=.o) \
+                    $(silk_tests_test_unit_LPC_inv_pred_gain_SOURCES:.c=.o)
 
 if HAVE_SSE
 SSE_OBJ = $(CELT_SOURCES_SSE:.c=.lo)
-$(SSE_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += $(OPUS_X86_SSE_CFLAGS)
+$(SSE_OBJ): CFLAGS += $(OPUS_X86_SSE_CFLAGS)
 endif
 
 if HAVE_SSE2
 SSE2_OBJ = $(CELT_SOURCES_SSE2:.c=.lo)
-$(SSE2_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += $(OPUS_X86_SSE2_CFLAGS)
+$(SSE2_OBJ): CFLAGS += $(OPUS_X86_SSE2_CFLAGS)
 endif
 
 if HAVE_SSE4_1
 SSE4_1_OBJ = $(CELT_SOURCES_SSE4_1:.c=.lo) \
              $(SILK_SOURCES_SSE4_1:.c=.lo) \
              $(SILK_SOURCES_FIXED_SSE4_1:.c=.lo)
-$(SSE4_1_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += $(OPUS_X86_SSE4_1_CFLAGS)
+$(SSE4_1_OBJ): CFLAGS += $(OPUS_X86_SSE4_1_CFLAGS)
 endif
 
 if HAVE_ARM_NEON_INTR
-ARM_NEON_INTR_OBJ = $(CELT_SOURCES_ARM_NEON_INTR:.c=.lo) $(SILK_SOURCES_ARM_NEON_INTR:.c=.lo)
-$(ARM_NEON_INTR_OBJ) $(OPT_UNIT_TEST_OBJ): CFLAGS += \
+ARM_NEON_INTR_OBJ = $(CELT_SOURCES_ARM_NEON_INTR:.c=.lo) \
+                    $(SILK_SOURCES_ARM_NEON_INTR:.c=.lo) \
+                    $(SILK_SOURCES_FIXED_ARM_NEON_INTR:.c=.lo)
+$(ARM_NEON_INTR_OBJ): CFLAGS += \
  $(OPUS_ARM_NEON_INTR_CFLAGS)  $(NE10_CFLAGS)
 endif
diff --git a/Makefile.mips b/Makefile.mips
index 56a5062..d25af8c 100644
--- a/Makefile.mips
+++ b/Makefile.mips
@@ -99,7 +99,7 @@
 TESTOPUSDECODE_SRCS_C = tests/test_opus_decode.c
 TESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C))
 
-TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c
+TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c tests/opus_encode_regressions.c
 TESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C))
 
 TESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c
diff --git a/Makefile.unix b/Makefile.unix
index b13230e..90a48f0 100644
--- a/Makefile.unix
+++ b/Makefile.unix
@@ -97,7 +97,7 @@
 TESTOPUSDECODE_SRCS_C = tests/test_opus_decode.c
 TESTOPUSDECODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSDECODE_SRCS_C))
 
-TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c
+TESTOPUSENCODE_SRCS_C = tests/test_opus_encode.c tests/opus_encode_regressions.c
 TESTOPUSENCODE_OBJS := $(patsubst %.c,%$(OBJSUFFIX),$(TESTOPUSENCODE_SRCS_C))
 
 TESTOPUSPADDING_SRCS_C = tests/test_opus_padding.c
diff --git a/README b/README
index ac6264e..f09766d 100644
--- a/README
+++ b/README
@@ -43,25 +43,43 @@
 
 To build from a distribution tarball, you only need to do the following:
 
-% ./configure
-% make
+    % ./configure
+    % make
 
 To build from the git repository, the following steps are necessary:
 
+0) Set up a development environment:
+
+On an Ubuntu or Debian family Linux distribution:
+
+    % sudo apt-get install git autoconf automake libtool gcc make
+
+On a Fedora/Redhat based Linux:
+
+    % sudo dnf install git autoconf automake libtool gcc make
+
+Or for older Redhat/Centos Linux releases:
+
+    % sudo yum install git autoconf automake libtool gcc make
+
+On Apple macOS, install Xcode and brew.sh, then in the Terminal enter:
+
+    % brew install autoconf automake libtool
+
 1) Clone the repository:
 
-% git clone https://git.xiph.org/opus.git
-% cd opus
+    % git clone https://git.xiph.org/opus.git
+    % cd opus
 
 2) Compiling the source
 
-% ./autogen.sh
-% ./configure
-% make
+    % ./autogen.sh
+    % ./configure
+    % make
 
 3) Install the codec libraries (optional)
 
-% sudo make install
+    % sudo make install
 
 Once you have compiled the codec, there will be a opus_demo executable
 in the top directory.
@@ -102,7 +120,8 @@
 time it is run on a new platform.
 
 To run the integrated tests:
-% make check
+
+    % make check
 
 There is also collection of standard test vectors which are not
 included in this package for size reasons but can be obtained from:
@@ -110,9 +129,9 @@
 
 To run compare the code to these test vectors:
 
-% curl -O https://opus-codec.org/testvectors/opus_testvectors.tar.gz
-% tar -zxf opus_testvectors.tar.gz
-% ./tests/run_vectors.sh ./ opus_testvectors 48000
+    % curl -O https://opus-codec.org/testvectors/opus_testvectors.tar.gz
+    % tar -zxf opus_testvectors.tar.gz
+    % ./tests/run_vectors.sh ./ opus_testvectors 48000
 
 == Portability notes ==
 
diff --git a/README.android b/README.android
index 2566b57..bcee085 100644
--- a/README.android
+++ b/README.android
@@ -1,4 +1,4 @@
-* current source is based on libopus 1.1.4 (https://git.xiph.org/?p=opus.git;a=snapshot;h=901c24328de6e07ebea8aa341433085cc39c59f9;sf=tgz)
+* current source is based on libopus 1.2.1 (https://git.xiph.org/?p=opus.git;a=snapshot;h=defbc370ec764d3d0dc43c45911e455b5e483b30;sf=tgz)
 * libopus is BSD-licensed - http://www.opus-codec.org/license/
 
 Updating:
diff --git a/README.version b/README.version
index 1700692..e4691e6 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,3 @@
-URL: https://git.xiph.org/?p=opus.git;a=snapshot;h=901c24328de6e07ebea8aa341433085cc39c59f9;sf=tgz
-Version: 1.1.4
+URL: https://git.xiph.org/?p=opus.git;a=snapshot;h=defbc370ec764d3d0dc43c45911e455b5e483b30;sf=tgz
+Version: 1.2.1
 BugComponent: 25690
diff --git a/autogen.sh b/autogen.sh
index 4de5f1c..380d1f3 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,4 +1,8 @@
 #!/bin/sh
+# Copyright (c) 2010-2015 Xiph.Org Foundation and contributors.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the COPYING file.
+
 # Run this to set up the build system: configure, makefiles, etc.
 set -e
 
diff --git a/celt/_kiss_fft_guts.h b/celt/_kiss_fft_guts.h
index 5e3d58f..17392b3 100644
--- a/celt/_kiss_fft_guts.h
+++ b/celt/_kiss_fft_guts.h
@@ -58,12 +58,12 @@
 #   define S_MUL(a,b) MULT16_32_Q15(b, a)
 
 #   define C_MUL(m,a,b) \
-      do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
-          (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
+      do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
+          (m).i = ADD32_ovflw(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
 
 #   define C_MULC(m,a,b) \
-      do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
-          (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
+      do{ (m).r = ADD32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
+          (m).i = SUB32_ovflw(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
 
 #   define C_MULBYSCALAR( c, s ) \
       do{ (c).r =  S_MUL( (c).r , s ) ;\
@@ -77,17 +77,17 @@
                 DIVSCALAR( (c).i  , div); }while (0)
 
 #define  C_ADD( res, a,b)\
-    do {(res).r=ADD32((a).r,(b).r);  (res).i=ADD32((a).i,(b).i); \
+    do {(res).r=ADD32_ovflw((a).r,(b).r);  (res).i=ADD32_ovflw((a).i,(b).i); \
     }while(0)
 #define  C_SUB( res, a,b)\
-    do {(res).r=SUB32((a).r,(b).r);  (res).i=SUB32((a).i,(b).i); \
+    do {(res).r=SUB32_ovflw((a).r,(b).r);  (res).i=SUB32_ovflw((a).i,(b).i); \
     }while(0)
 #define C_ADDTO( res , a)\
-    do {(res).r = ADD32((res).r, (a).r);  (res).i = ADD32((res).i,(a).i);\
+    do {(res).r = ADD32_ovflw((res).r, (a).r);  (res).i = ADD32_ovflw((res).i,(a).i);\
     }while(0)
 
 #define C_SUBFROM( res , a)\
-    do {(res).r = ADD32((res).r,(a).r);  (res).i = SUB32((res).i,(a).i); \
+    do {(res).r = ADD32_ovflw((res).r,(a).r);  (res).i = SUB32_ovflw((res).i,(a).i); \
     }while(0)
 
 #if defined(OPUS_ARM_INLINE_ASM)
diff --git a/celt/arch.h b/celt/arch.h
index 8ceab5f..d1e6457 100644
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -46,6 +46,14 @@
 #  endif
 # endif
 
+#if OPUS_GNUC_PREREQ(3, 0)
+#define opus_likely(x)       (__builtin_expect(!!(x), 1))
+#define opus_unlikely(x)     (__builtin_expect(!!(x), 0))
+#else
+#define opus_likely(x)       (!!(x))
+#define opus_unlikely(x)     (!!(x))
+#endif
+
 #define CELT_SIG_SCALE 32768.f
 
 #define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
@@ -93,6 +101,7 @@
 
 typedef opus_int16 opus_val16;
 typedef opus_int32 opus_val32;
+typedef opus_int64 opus_val64;
 
 typedef opus_val32 celt_sig;
 typedef opus_val16 celt_norm;
@@ -101,6 +110,9 @@
 #define Q15ONE 32767
 
 #define SIG_SHIFT 12
+/* Safe saturation value for 32-bit signals. Should be less than
+   2^31*(1-0.85) to avoid blowing up on DC at deemphasis.*/
+#define SIG_SAT (300000000)
 
 #define NORM_SCALING 16384
 
@@ -147,6 +159,7 @@
 
 typedef float opus_val16;
 typedef float opus_val32;
+typedef float opus_val64;
 
 typedef float celt_sig;
 typedef float celt_norm;
@@ -186,6 +199,7 @@
 
 #define NEG16(x) (-(x))
 #define NEG32(x) (-(x))
+#define NEG32_ovflw(x) (-(x))
 #define EXTRACT16(x) (x)
 #define EXTEND32(x) (x)
 #define SHR16(a,shift) (a)
@@ -202,6 +216,7 @@
 #define SATURATE16(x)   (x)
 
 #define ROUND16(a,shift)  (a)
+#define SROUND16(a,shift) (a)
 #define HALF16(x)       (.5f*(x))
 #define HALF32(x)       (.5f*(x))
 
@@ -209,6 +224,8 @@
 #define SUB16(a,b) ((a)-(b))
 #define ADD32(a,b) ((a)+(b))
 #define SUB32(a,b) ((a)-(b))
+#define ADD32_ovflw(a,b) ((a)+(b))
+#define SUB32_ovflw(a,b) ((a)-(b))
 #define MULT16_16_16(a,b)     ((a)*(b))
 #define MULT16_16(a,b)     ((opus_val32)(a)*(opus_val32)(b))
 #define MAC16_16(c,a,b)     ((c)+(opus_val32)(a)*(opus_val32)(b))
@@ -243,9 +260,9 @@
 
 #ifndef GLOBAL_STACK_SIZE
 #ifdef FIXED_POINT
-#define GLOBAL_STACK_SIZE 100000
+#define GLOBAL_STACK_SIZE 120000
 #else
-#define GLOBAL_STACK_SIZE 100000
+#define GLOBAL_STACK_SIZE 120000
 #endif
 #endif
 
diff --git a/celt/arm/arm2gnu.pl b/celt/arm/arm2gnu.pl
index 6c922ac..a2895f7 100755
--- a/celt/arm/arm2gnu.pl
+++ b/celt/arm/arm2gnu.pl
@@ -164,11 +164,11 @@
         $prefix = "";
         if ($proc)
         {
-            $prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc) unless ($apple);
+            $prefix = $prefix.sprintf("\t.type\t%s, %%function", $proc) unless ($apple);
             # Make sure we $prefix isn't empty here (for the $apple case).
             # We handle mangling the label here, make sure it doesn't match
             # the label handling below (if $prefix would be empty).
-            $prefix = "; ";
+            $prefix = $prefix."; ";
             push(@proc_stack, $proc);
             s/^[A-Za-z_\.]\w+/$symprefix$&:/;
         }
diff --git a/celt/arm/arm_celt_map.c b/celt/arm/arm_celt_map.c
index 4d4d069..ca988b6 100644
--- a/celt/arm/arm_celt_map.c
+++ b/celt/arm/arm_celt_map.c
@@ -35,12 +35,29 @@
 
 #if defined(OPUS_HAVE_RTCD)
 
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
+opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N) = {
+  celt_inner_prod_c,   /* ARMv4 */
+  celt_inner_prod_c,   /* EDSP */
+  celt_inner_prod_c,   /* Media */
+  celt_inner_prod_neon /* NEON */
+};
+
+void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
+      int N, opus_val32 *xy1, opus_val32 *xy2) = {
+  dual_inner_prod_c,   /* ARMv4 */
+  dual_inner_prod_c,   /* EDSP */
+  dual_inner_prod_c,   /* Media */
+  dual_inner_prod_neon /* NEON */
+};
+# endif
+
 # if defined(FIXED_POINT)
 #  if ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
     (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
     (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
 opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
-    const opus_val16 *, opus_val32 *, int , int) = {
+    const opus_val16 *, opus_val32 *, int, int, int) = {
   celt_pitch_xcorr_c,               /* ARMv4 */
   MAY_HAVE_EDSP(celt_pitch_xcorr),  /* EDSP */
   MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
@@ -51,7 +68,7 @@
 # else /* !FIXED_POINT */
 #  if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
 void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
-    const opus_val16 *, opus_val32 *, int, int) = {
+    const opus_val16 *, opus_val32 *, int, int, int) = {
   celt_pitch_xcorr_c,              /* ARMv4 */
   celt_pitch_xcorr_c,              /* EDSP */
   celt_pitch_xcorr_c,              /* Media */
diff --git a/celt/arm/celt_ne10_fft.c b/celt/arm/celt_ne10_fft.c
index 42d96a7..b8c60ab 100644
--- a/celt/arm/celt_ne10_fft.c
+++ b/celt/arm/celt_ne10_fft.c
@@ -36,7 +36,6 @@
 #endif
 #endif
 
-#include <NE10_init.h>
 #include <NE10_dsp.h>
 #include "os_support.h"
 #include "kiss_fft.h"
diff --git a/celt/arm/celt_neon_intr.c b/celt/arm/celt_neon_intr.c
index 47bbe3d..cf44398 100644
--- a/celt/arm/celt_neon_intr.c
+++ b/celt/arm/celt_neon_intr.c
@@ -191,107 +191,10 @@
    vst1q_f32(sum, SUMM);
 }
 
-/*
- * Function: xcorr_kernel_neon_float_process1
- * ---------------------------------
- * Computes single correlation values and stores in *sum
- */
-static void xcorr_kernel_neon_float_process1(const float32_t *x,
-      const float32_t *y, float32_t *sum, int len) {
-   float32x4_t XX[4];
-   float32x4_t YY[4];
-   float32x2_t XX_2;
-   float32x2_t YY_2;
-   float32x4_t SUMM;
-   float32x2_t SUMM_2[2];
-   const float32_t *xi = x;
-   const float32_t *yi = y;
-
-   SUMM = vdupq_n_f32(0);
-
-   /* Work on 16 values per iteration */
-   while (len >= 16) {
-      XX[0] = vld1q_f32(xi);
-      xi += 4;
-      XX[1] = vld1q_f32(xi);
-      xi += 4;
-      XX[2] = vld1q_f32(xi);
-      xi += 4;
-      XX[3] = vld1q_f32(xi);
-      xi += 4;
-
-      YY[0] = vld1q_f32(yi);
-      yi += 4;
-      YY[1] = vld1q_f32(yi);
-      yi += 4;
-      YY[2] = vld1q_f32(yi);
-      yi += 4;
-      YY[3] = vld1q_f32(yi);
-      yi += 4;
-
-      SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
-      SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);
-      SUMM = vmlaq_f32(SUMM, YY[2], XX[2]);
-      SUMM = vmlaq_f32(SUMM, YY[3], XX[3]);
-      len -= 16;
-   }
-
-   /* Work on 8 values */
-   if (len >= 8) {
-      XX[0] = vld1q_f32(xi);
-      xi += 4;
-      XX[1] = vld1q_f32(xi);
-      xi += 4;
-
-      YY[0] = vld1q_f32(yi);
-      yi += 4;
-      YY[1] = vld1q_f32(yi);
-      yi += 4;
-
-      SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
-      SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);
-      len -= 8;
-   }
-
-   /* Work on 4 values */
-   if (len >= 4) {
-      XX[0] = vld1q_f32(xi);
-      xi += 4;
-      YY[0] = vld1q_f32(yi);
-      yi += 4;
-      SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
-      len -= 4;
-   }
-
-   /* Start accumulating results */
-   SUMM_2[0] = vget_low_f32(SUMM);
-   if (len >= 2) {
-      /* While at it, consume 2 more values if available */
-      XX_2 = vld1_f32(xi);
-      xi += 2;
-      YY_2 = vld1_f32(yi);
-      yi += 2;
-      SUMM_2[0] = vmla_f32(SUMM_2[0], YY_2, XX_2);
-      len -= 2;
-   }
-   SUMM_2[1] = vget_high_f32(SUMM);
-   SUMM_2[0] = vadd_f32(SUMM_2[0], SUMM_2[1]);
-   SUMM_2[0] = vpadd_f32(SUMM_2[0], SUMM_2[0]);
-   /* Ok, now we have result accumulated in SUMM_2[0].0 */
-
-   if (len > 0) {
-      /* Case when you have one value left */
-      XX_2 = vld1_dup_f32(xi);
-      YY_2 = vld1_dup_f32(yi);
-      SUMM_2[0] = vmla_f32(SUMM_2[0], XX_2, YY_2);
-   }
-
-   vst1_lane_f32(sum, SUMM_2[0], 0);
-}
-
 void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
-                        opus_val32 *xcorr, int len, int max_pitch) {
+                        opus_val32 *xcorr, int len, int max_pitch, int arch) {
    int i;
+   (void)arch;
    celt_assert(max_pitch > 0);
    celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
 
@@ -300,12 +203,9 @@
             (float32_t *)xcorr+i, len);
    }
 
-   /* In case max_pitch isn't multiple of 4
-    * compute single correlation value per iteration
-    */
+   /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */
    for (; i < max_pitch; i++) {
-      xcorr_kernel_neon_float_process1((const float32_t *)_x,
-            (const float32_t *)_y+i, (float32_t *)xcorr+i, len);
+      xcorr[i] = celt_inner_prod_neon(_x, _y+i, len);
    }
 }
 #endif
diff --git a/celt/arm/celt_pitch_xcorr_arm_gnu.s b/celt/arm/celt_pitch_xcorr_arm_gnu.s
index 4be1705..31b0c65 100644
--- a/celt/arm/celt_pitch_xcorr_arm_gnu.s
+++ b/celt/arm/celt_pitch_xcorr_arm_gnu.s
@@ -44,7 +44,7 @@
  .if OPUS_ARM_MAY_HAVE_NEON
 
 @ Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3
-; xcorr_kernel_neon: @ PROC
+	.type	xcorr_kernel_neon, %function; xcorr_kernel_neon: @ PROC
 xcorr_kernel_neon_start:
   @ input:
   @   r3     = int         len
@@ -156,8 +156,8 @@
 	.size xcorr_kernel_neon, .-xcorr_kernel_neon  @ ENDP
 
 @ opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
-@  opus_val32 *xcorr, int len, int max_pitch)
-; celt_pitch_xcorr_neon: @ PROC
+@  opus_val32 *xcorr, int len, int max_pitch, int arch)
+	.type	celt_pitch_xcorr_neon, %function; celt_pitch_xcorr_neon: @ PROC
   @ input:
   @   r0  = opus_val16 *_x
   @   r1  = opus_val16 *_y
@@ -171,6 +171,8 @@
   @   r6  = int         max_pitch
   @   r12 = int         j
   @   q15 = int         maxcorr[4] (q15 is not used by xcorr_kernel_neon())
+  @ ignored:
+  @         int         arch
   STMFD        sp!, {r4-r6, lr}
   LDR          r6, [sp, #16]
   VMOV.S32     q15, #1
@@ -260,7 +262,7 @@
 
 @ This will get used on ARMv7 devices without NEON, so it has been optimized
 @ to take advantage of dual-issuing where possible.
-; xcorr_kernel_edsp: @ PROC
+	.type	xcorr_kernel_edsp, %function; xcorr_kernel_edsp: @ PROC
 xcorr_kernel_edsp_start:
   @ input:
   @   r3      = int         len
@@ -344,7 +346,7 @@
   LDMFD        sp!, {r2,r4,r5,pc}
 	.size xcorr_kernel_edsp, .-xcorr_kernel_edsp  @ ENDP
 
-; celt_pitch_xcorr_edsp: @ PROC
+	.type	celt_pitch_xcorr_edsp, %function; celt_pitch_xcorr_edsp: @ PROC
   @ input:
   @   r0  = opus_val16 *_x (must be 32-bit aligned)
   @   r1  = opus_val16 *_y (only needs to be 16-bit aligned)
@@ -361,6 +363,8 @@
   @   r9  = opus_val32  sum3
   @   r1  = int         max_pitch
   @   r12 = int         j
+  @ ignored:
+  @         int         arch
   STMFD        sp!, {r4-r11, lr}
   MOV          r5, r1
   LDR          r1, [sp, #36]
diff --git a/celt/arm/fft_arm.h b/celt/arm/fft_arm.h
index 0cb55d8..0b78175 100644
--- a/celt/arm/fft_arm.h
+++ b/celt/arm/fft_arm.h
@@ -34,7 +34,6 @@
 #if !defined(FFT_ARM_H)
 #define FFT_ARM_H
 
-#include "config.h"
 #include "kiss_fft.h"
 
 #if defined(HAVE_ARM_NE10)
diff --git a/celt/arm/fixed_armv4.h b/celt/arm/fixed_armv4.h
index efb3b18..d84888a 100644
--- a/celt/arm/fixed_armv4.h
+++ b/celt/arm/fixed_armv4.h
@@ -37,7 +37,7 @@
       "#MULT16_32_Q16\n\t"
       "smull %0, %1, %2, %3\n\t"
       : "=&r"(rd_lo), "=&r"(rd_hi)
-      : "%r"(b),"r"(a<<16)
+      : "%r"(b),"r"(SHL32(a,16))
   );
   return rd_hi;
 }
@@ -54,10 +54,10 @@
       "#MULT16_32_Q15\n\t"
       "smull %0, %1, %2, %3\n\t"
       : "=&r"(rd_lo), "=&r"(rd_hi)
-      : "%r"(b), "r"(a<<16)
+      : "%r"(b), "r"(SHL32(a,16))
   );
   /*We intentionally don't OR in the high bit of rd_lo for speed.*/
-  return rd_hi<<1;
+  return SHL32(rd_hi,1);
 }
 #define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b))
 
diff --git a/celt/arm/fixed_armv5e.h b/celt/arm/fixed_armv5e.h
index 36a6321..6bf73cb 100644
--- a/celt/arm/fixed_armv5e.h
+++ b/celt/arm/fixed_armv5e.h
@@ -59,7 +59,7 @@
       : "=r"(res)
       : "r"(b), "r"(a)
   );
-  return res<<1;
+  return SHL32(res,1);
 }
 #define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
 
@@ -76,7 +76,7 @@
       "#MAC16_32_Q15\n\t"
       "smlawb %0, %1, %2, %3;\n"
       : "=r"(res)
-      : "r"(b<<1), "r"(a), "r"(c)
+      : "r"(SHL32(b,1)), "r"(a), "r"(c)
   );
   return res;
 }
diff --git a/celt/arm/mdct_arm.h b/celt/arm/mdct_arm.h
index 49cbb44..14200ba 100644
--- a/celt/arm/mdct_arm.h
+++ b/celt/arm/mdct_arm.h
@@ -33,7 +33,6 @@
 #if !defined(MDCT_ARM_H)
 #define MDCT_ARM_H
 
-#include "config.h"
 #include "mdct.h"
 
 #if defined(HAVE_ARM_NE10)
diff --git a/celt/arm/pitch_arm.h b/celt/arm/pitch_arm.h
index 1433116..4ee13bd 100644
--- a/celt/arm/pitch_arm.h
+++ b/celt/arm/pitch_arm.h
@@ -30,11 +30,47 @@
 
 # include "armcpu.h"
 
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N);
+void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01,
+        const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
+
+#  if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
+#   define OVERRIDE_CELT_INNER_PROD (1)
+#   define OVERRIDE_DUAL_INNER_PROD (1)
+#   define celt_inner_prod(x, y, N, arch) ((void)(arch), PRESUME_NEON(celt_inner_prod)(x, y, N))
+#   define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), PRESUME_NEON(dual_inner_prod)(x, y01, y02, N, xy1, xy2))
+#  endif
+# endif
+
+# if !defined(OVERRIDE_CELT_INNER_PROD)
+#  if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N);
+#   define OVERRIDE_CELT_INNER_PROD (1)
+#   define celt_inner_prod(x, y, N, arch) ((*CELT_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y, N))
+#  elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+#   define OVERRIDE_CELT_INNER_PROD (1)
+#   define celt_inner_prod(x, y, N, arch) ((void)(arch), celt_inner_prod_neon(x, y, N))
+#  endif
+# endif
+
+# if !defined(OVERRIDE_DUAL_INNER_PROD)
+#  if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x,
+        const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
+#   define OVERRIDE_DUAL_INNER_PROD (1)
+#   define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((*DUAL_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))
+#  elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+#   define OVERRIDE_DUAL_INNER_PROD (1)
+#   define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), dual_inner_prod_neon(x, y01, y02, N, xy1, xy2))
+#  endif
+# endif
+
 # if defined(FIXED_POINT)
 
 #  if defined(OPUS_ARM_MAY_HAVE_NEON)
 opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
-    opus_val32 *xcorr, int len, int max_pitch);
+    opus_val32 *xcorr, int len, int max_pitch, int arch);
 #  endif
 
 #  if defined(OPUS_ARM_MAY_HAVE_MEDIA)
@@ -43,7 +79,7 @@
 
 #  if defined(OPUS_ARM_MAY_HAVE_EDSP)
 opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
-    opus_val32 *xcorr, int len, int max_pitch);
+    opus_val32 *xcorr, int len, int max_pitch, int arch);
 #  endif
 
 #  if defined(OPUS_HAVE_RTCD) && \
@@ -52,18 +88,15 @@
      (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
 extern opus_val32
 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
-      const opus_val16 *, opus_val32 *, int, int);
+      const opus_val16 *, opus_val32 *, int, int, int);
 #   define OVERRIDE_PITCH_XCORR (1)
-#   define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
-  ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
-        xcorr, len, max_pitch))
+#   define celt_pitch_xcorr (*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])
 
 #  elif defined(OPUS_ARM_PRESUME_EDSP) || \
     defined(OPUS_ARM_PRESUME_MEDIA) || \
     defined(OPUS_ARM_PRESUME_NEON)
 #   define OVERRIDE_PITCH_XCORR (1)
-#   define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
-  ((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch))
+#   define celt_pitch_xcorr (PRESUME_NEON(celt_pitch_xcorr))
 
 #  endif
 
@@ -99,25 +132,22 @@
 /* Float case */
 #if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
 void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
-                                 opus_val32 *xcorr, int len, int max_pitch);
+                                 opus_val32 *xcorr, int len, int max_pitch, int arch);
 #endif
 
 #  if defined(OPUS_HAVE_RTCD) && \
     (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
 extern void
 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
-      const opus_val16 *, opus_val32 *, int, int);
+      const opus_val16 *, opus_val32 *, int, int, int);
 
 #  define OVERRIDE_PITCH_XCORR (1)
-#  define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
-  ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
-        xcorr, len, max_pitch))
+#  define celt_pitch_xcorr (*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])
 
 #  elif defined(OPUS_ARM_PRESUME_NEON_INTR)
 
 #   define OVERRIDE_PITCH_XCORR (1)
-#   define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
-   ((void)(arch),celt_pitch_xcorr_float_neon(_x, _y, xcorr, len, max_pitch))
+#   define celt_pitch_xcorr celt_pitch_xcorr_float_neon
 
 #  endif
 
diff --git a/celt/arm/pitch_neon_intr.c b/celt/arm/pitch_neon_intr.c
new file mode 100644
index 0000000..1ac38c4
--- /dev/null
+++ b/celt/arm/pitch_neon_intr.c
@@ -0,0 +1,290 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <arm_neon.h>
+#include "pitch.h"
+
+#ifdef FIXED_POINT
+
+opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
+{
+    int i;
+    opus_val32 xy;
+    int16x8_t x_s16x8, y_s16x8;
+    int32x4_t xy_s32x4 = vdupq_n_s32(0);
+    int64x2_t xy_s64x2;
+    int64x1_t xy_s64x1;
+
+    for (i = 0; i < N - 7; i += 8) {
+        x_s16x8  = vld1q_s16(&x[i]);
+        y_s16x8  = vld1q_s16(&y[i]);
+        xy_s32x4 = vmlal_s16(xy_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y_s16x8));
+        xy_s32x4 = vmlal_s16(xy_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y_s16x8));
+    }
+
+    if (N - i >= 4) {
+        const int16x4_t x_s16x4 = vld1_s16(&x[i]);
+        const int16x4_t y_s16x4 = vld1_s16(&y[i]);
+        xy_s32x4 = vmlal_s16(xy_s32x4, x_s16x4, y_s16x4);
+        i += 4;
+    }
+
+    xy_s64x2 = vpaddlq_s32(xy_s32x4);
+    xy_s64x1 = vadd_s64(vget_low_s64(xy_s64x2), vget_high_s64(xy_s64x2));
+    xy       = vget_lane_s32(vreinterpret_s32_s64(xy_s64x1), 0);
+
+    for (; i < N; i++) {
+        xy = MAC16_16(xy, x[i], y[i]);
+    }
+
+#ifdef OPUS_CHECK_ASM
+    celt_assert(celt_inner_prod_c(x, y, N) == xy);
+#endif
+
+    return xy;
+}
+
+void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
+        int N, opus_val32 *xy1, opus_val32 *xy2)
+{
+    int i;
+    opus_val32 xy01, xy02;
+    int16x8_t x_s16x8, y01_s16x8, y02_s16x8;
+    int32x4_t xy01_s32x4 = vdupq_n_s32(0);
+    int32x4_t xy02_s32x4 = vdupq_n_s32(0);
+    int64x2_t xy01_s64x2, xy02_s64x2;
+    int64x1_t xy01_s64x1, xy02_s64x1;
+
+    for (i = 0; i < N - 7; i += 8) {
+        x_s16x8    = vld1q_s16(&x[i]);
+        y01_s16x8  = vld1q_s16(&y01[i]);
+        y02_s16x8  = vld1q_s16(&y02[i]);
+        xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y01_s16x8));
+        xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y02_s16x8));
+        xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y01_s16x8));
+        xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y02_s16x8));
+    }
+
+    if (N - i >= 4) {
+        const int16x4_t x_s16x4   = vld1_s16(&x[i]);
+        const int16x4_t y01_s16x4 = vld1_s16(&y01[i]);
+        const int16x4_t y02_s16x4 = vld1_s16(&y02[i]);
+        xy01_s32x4 = vmlal_s16(xy01_s32x4, x_s16x4, y01_s16x4);
+        xy02_s32x4 = vmlal_s16(xy02_s32x4, x_s16x4, y02_s16x4);
+        i += 4;
+    }
+
+    xy01_s64x2 = vpaddlq_s32(xy01_s32x4);
+    xy02_s64x2 = vpaddlq_s32(xy02_s32x4);
+    xy01_s64x1 = vadd_s64(vget_low_s64(xy01_s64x2), vget_high_s64(xy01_s64x2));
+    xy02_s64x1 = vadd_s64(vget_low_s64(xy02_s64x2), vget_high_s64(xy02_s64x2));
+    xy01       = vget_lane_s32(vreinterpret_s32_s64(xy01_s64x1), 0);
+    xy02       = vget_lane_s32(vreinterpret_s32_s64(xy02_s64x1), 0);
+
+    for (; i < N; i++) {
+        xy01 = MAC16_16(xy01, x[i], y01[i]);
+        xy02 = MAC16_16(xy02, x[i], y02[i]);
+    }
+    *xy1 = xy01;
+    *xy2 = xy02;
+
+#ifdef OPUS_CHECK_ASM
+    {
+        opus_val32 xy1_c, xy2_c;
+        dual_inner_prod_c(x, y01, y02, N, &xy1_c, &xy2_c);
+        celt_assert(xy1_c == *xy1);
+        celt_assert(xy2_c == *xy2);
+    }
+#endif
+}
+
+#else /* !FIXED_POINT */
+
+/* ========================================================================== */
+
+#ifdef OPUS_CHECK_ASM
+
+/* This part of code simulates floating-point NEON operations. */
+
+/* celt_inner_prod_neon_float_c_simulation() simulates the floating-point   */
+/* operations of celt_inner_prod_neon(), and both functions should have bit */
+/* exact output.                                                            */
+static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, int N)
+{
+   int i;
+   opus_val32 xy, xy0 = 0, xy1 = 0, xy2 = 0, xy3 = 0;
+   for (i = 0; i < N - 3; i += 4) {
+      xy0 = MAC16_16(xy0, x[i + 0], y[i + 0]);
+      xy1 = MAC16_16(xy1, x[i + 1], y[i + 1]);
+      xy2 = MAC16_16(xy2, x[i + 2], y[i + 2]);
+      xy3 = MAC16_16(xy3, x[i + 3], y[i + 3]);
+   }
+   xy0 += xy2;
+   xy1 += xy3;
+   xy = xy0 + xy1;
+   for (; i < N; i++) {
+      xy = MAC16_16(xy, x[i], y[i]);
+   }
+   return xy;
+}
+
+/* dual_inner_prod_neon_float_c_simulation() simulates the floating-point   */
+/* operations of dual_inner_prod_neon(), and both functions should have bit */
+/* exact output.                                                            */
+static void dual_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
+      int N, opus_val32 *xy1, opus_val32 *xy2)
+{
+   int i;
+   opus_val32 xy01, xy02, xy01_0 = 0, xy01_1 = 0, xy01_2 = 0, xy01_3 = 0, xy02_0 = 0, xy02_1 = 0, xy02_2 = 0, xy02_3 = 0;
+   for (i = 0; i < N - 3; i += 4) {
+      xy01_0 = MAC16_16(xy01_0, x[i + 0], y01[i + 0]);
+      xy01_1 = MAC16_16(xy01_1, x[i + 1], y01[i + 1]);
+      xy01_2 = MAC16_16(xy01_2, x[i + 2], y01[i + 2]);
+      xy01_3 = MAC16_16(xy01_3, x[i + 3], y01[i + 3]);
+      xy02_0 = MAC16_16(xy02_0, x[i + 0], y02[i + 0]);
+      xy02_1 = MAC16_16(xy02_1, x[i + 1], y02[i + 1]);
+      xy02_2 = MAC16_16(xy02_2, x[i + 2], y02[i + 2]);
+      xy02_3 = MAC16_16(xy02_3, x[i + 3], y02[i + 3]);
+   }
+   xy01_0 += xy01_2;
+   xy02_0 += xy02_2;
+   xy01_1 += xy01_3;
+   xy02_1 += xy02_3;
+   xy01 = xy01_0 + xy01_1;
+   xy02 = xy02_0 + xy02_1;
+   for (; i < N; i++) {
+      xy01 = MAC16_16(xy01, x[i], y01[i]);
+      xy02 = MAC16_16(xy02, x[i], y02[i]);
+   }
+   *xy1 = xy01;
+   *xy2 = xy02;
+}
+
+#endif /* OPUS_CHECK_ASM */
+
+/* ========================================================================== */
+
+opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
+{
+    int i;
+    opus_val32 xy;
+    float32x4_t xy_f32x4 = vdupq_n_f32(0);
+    float32x2_t xy_f32x2;
+
+    for (i = 0; i < N - 7; i += 8) {
+        float32x4_t x_f32x4, y_f32x4;
+        x_f32x4  = vld1q_f32(&x[i]);
+        y_f32x4  = vld1q_f32(&y[i]);
+        xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
+        x_f32x4  = vld1q_f32(&x[i + 4]);
+        y_f32x4  = vld1q_f32(&y[i + 4]);
+        xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
+    }
+
+    if (N - i >= 4) {
+        const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
+        const float32x4_t y_f32x4 = vld1q_f32(&y[i]);
+        xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
+        i += 4;
+    }
+
+    xy_f32x2 = vadd_f32(vget_low_f32(xy_f32x4), vget_high_f32(xy_f32x4));
+    xy_f32x2 = vpadd_f32(xy_f32x2, xy_f32x2);
+    xy       = vget_lane_f32(xy_f32x2, 0);
+
+    for (; i < N; i++) {
+        xy = MAC16_16(xy, x[i], y[i]);
+    }
+
+#ifdef OPUS_CHECK_ASM
+    celt_assert(ABS32(celt_inner_prod_neon_float_c_simulation(x, y, N) - xy) <= VERY_SMALL);
+#endif
+
+    return xy;
+}
+
+void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
+        int N, opus_val32 *xy1, opus_val32 *xy2)
+{
+    int i;
+    opus_val32 xy01, xy02;
+    float32x4_t xy01_f32x4 = vdupq_n_f32(0);
+    float32x4_t xy02_f32x4 = vdupq_n_f32(0);
+    float32x2_t xy01_f32x2, xy02_f32x2;
+
+    for (i = 0; i < N - 7; i += 8) {
+        float32x4_t x_f32x4, y01_f32x4, y02_f32x4;
+        x_f32x4    = vld1q_f32(&x[i]);
+        y01_f32x4  = vld1q_f32(&y01[i]);
+        y02_f32x4  = vld1q_f32(&y02[i]);
+        xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
+        xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
+        x_f32x4    = vld1q_f32(&x[i + 4]);
+        y01_f32x4  = vld1q_f32(&y01[i + 4]);
+        y02_f32x4  = vld1q_f32(&y02[i + 4]);
+        xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
+        xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
+    }
+
+    if (N - i >= 4) {
+        const float32x4_t x_f32x4   = vld1q_f32(&x[i]);
+        const float32x4_t y01_f32x4 = vld1q_f32(&y01[i]);
+        const float32x4_t y02_f32x4 = vld1q_f32(&y02[i]);
+        xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
+        xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
+        i += 4;
+    }
+
+    xy01_f32x2 = vadd_f32(vget_low_f32(xy01_f32x4), vget_high_f32(xy01_f32x4));
+    xy02_f32x2 = vadd_f32(vget_low_f32(xy02_f32x4), vget_high_f32(xy02_f32x4));
+    xy01_f32x2 = vpadd_f32(xy01_f32x2, xy01_f32x2);
+    xy02_f32x2 = vpadd_f32(xy02_f32x2, xy02_f32x2);
+    xy01       = vget_lane_f32(xy01_f32x2, 0);
+    xy02       = vget_lane_f32(xy02_f32x2, 0);
+
+    for (; i < N; i++) {
+        xy01 = MAC16_16(xy01, x[i], y01[i]);
+        xy02 = MAC16_16(xy02, x[i], y02[i]);
+    }
+    *xy1 = xy01;
+    *xy2 = xy02;
+
+#ifdef OPUS_CHECK_ASM
+    {
+        opus_val32 xy1_c, xy2_c;
+        dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c);
+        celt_assert(ABS32(xy1_c - *xy1) <= VERY_SMALL);
+        celt_assert(ABS32(xy2_c - *xy2) <= VERY_SMALL);
+    }
+#endif
+}
+
+#endif /* FIXED_POINT */
diff --git a/celt/bands.c b/celt/bands.c
index 87eaa6c..3b1f5cf 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -65,7 +65,7 @@
 
 /* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
    with this approximation is important because it has an impact on the bit allocation */
-static opus_int16 bitexact_cos(opus_int16 x)
+opus_int16 bitexact_cos(opus_int16 x)
 {
    opus_int32 tmp;
    opus_int16 x2;
@@ -77,7 +77,7 @@
    return 1+x2;
 }
 
-static int bitexact_log2tan(int isin,int icos)
+int bitexact_log2tan(int isin,int icos)
 {
    int lc;
    int ls;
@@ -92,10 +92,11 @@
 
 #ifdef FIXED_POINT
 /* Compute the amplitude (sqrt energy) in each of the bands */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch)
 {
    int i, c, N;
    const opus_int16 *eBands = m->eBands;
+   (void)arch;
    N = m->shortMdctSize<<LM;
    c=0; do {
       for (i=0;i<end;i++)
@@ -155,7 +156,7 @@
 
 #else /* FIXED_POINT */
 /* Compute the amplitude (sqrt energy) in each of the bands */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch)
 {
    int i, c, N;
    const opus_int16 *eBands = m->eBands;
@@ -164,7 +165,7 @@
       for (i=0;i<end;i++)
       {
          opus_val32 sum;
-         sum = 1e-27f + celt_inner_prod_c(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);
+         sum = 1e-27f + celt_inner_prod(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM, arch);
          bandE[i+c*m->nbEBands] = celt_sqrt(sum);
          /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
       }
@@ -224,9 +225,9 @@
 #endif
       j=M*eBands[i];
       band_end = M*eBands[i+1];
-      lg = ADD16(bandLogE[i], SHL16((opus_val16)eMeans[i],6));
+      lg = SATURATE16(ADD32(bandLogE[i], SHL32((opus_val32)eMeans[i],6)));
 #ifndef FIXED_POINT
-      g = celt_exp2(lg);
+      g = celt_exp2(MIN32(32.f, lg));
 #else
       /* Handle the integer part of the log energy */
       shift = 16-(lg>>DB_SHIFT);
@@ -241,12 +242,12 @@
       /* Handle extreme gains with negative shift. */
       if (shift<0)
       {
-         /* For shift < -2 we'd be likely to overflow, so we're capping
-               the gain here. This shouldn't happen unless the bitstream is
-               already corrupted. */
-         if (shift < -2)
+         /* For shift <= -2 and g > 16384 we'd be likely to overflow, so we're
+            capping the gain here, which is equivalent to a cap of 18 on lg.
+            This shouldn't trigger unless the bitstream is already corrupted. */
+         if (shift <= -2)
          {
-            g = 32767;
+            g = 16384;
             shift = -2;
          }
          do {
@@ -360,6 +361,30 @@
    }
 }
 
+/* Compute the weights to use for optimizing normalized distortion across
+   channels. We use the amplitude to weight square distortion, which means
+   that we use the square root of the value we would have been using if we
+   wanted to minimize the MSE in the non-normalized domain. This roughly
+   corresponds to some quick-and-dirty perceptual experiments I ran to
+   measure inter-aural masking (there doesn't seem to be any published data
+   on the topic). */
+static void compute_channel_weights(celt_ener Ex, celt_ener Ey, opus_val16 w[2])
+{
+   celt_ener minE;
+#if FIXED_POINT
+   int shift;
+#endif
+   minE = MIN32(Ex, Ey);
+   /* Adjustment to make the weights a bit more conservative. */
+   Ex = ADD32(Ex, minE/3);
+   Ey = ADD32(Ey, minE/3);
+#if FIXED_POINT
+   shift = celt_ilog2(EPSILON+MAX32(Ex, Ey))-14;
+#endif
+   w[0] = VSHR32(Ex, shift);
+   w[1] = VSHR32(Ey, shift);
+}
+
 static void intensity_stereo(const CELTMode *m, celt_norm * OPUS_RESTRICT X, const celt_norm * OPUS_RESTRICT Y, const celt_ener *bandE, int bandID, int N)
 {
    int i = bandID;
@@ -647,6 +672,7 @@
 
 struct band_ctx {
    int encode;
+   int resynth;
    const CELTMode *m;
    int i;
    int intensity;
@@ -657,6 +683,9 @@
    const celt_ener *bandE;
    opus_uint32 seed;
    int arch;
+   int theta_round;
+   int disable_inv;
+   int avoid_split_noise;
 };
 
 struct split_ctx {
@@ -714,8 +743,35 @@
    if (qn!=1)
    {
       if (encode)
-         itheta = (itheta*(opus_int32)qn+8192)>>14;
-
+      {
+         if (!stereo || ctx->theta_round == 0)
+         {
+            itheta = (itheta*(opus_int32)qn+8192)>>14;
+            if (!stereo && ctx->avoid_split_noise && itheta > 0 && itheta < qn)
+            {
+               /* Check if the selected value of theta will cause the bit allocation
+                  to inject noise on one side. If so, make sure the energy of that side
+                  is zero. */
+               int unquantized = celt_udiv((opus_int32)itheta*16384, qn);
+               imid = bitexact_cos((opus_int16)unquantized);
+               iside = bitexact_cos((opus_int16)(16384-unquantized));
+               delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
+               if (delta > *b)
+                  itheta = qn;
+               else if (delta < -*b)
+                  itheta = 0;
+            }
+         } else {
+            int down;
+            /* Bias quantization towards itheta=0 and itheta=16384. */
+            int bias = itheta > 8192 ? 32767/qn : -32767/qn;
+            down = IMIN(qn-1, IMAX(0, (itheta*(opus_int32)qn + bias)>>14));
+            if (ctx->theta_round < 0)
+               itheta = down;
+            else
+               itheta = down+1;
+         }
+      }
       /* Entropy coding of the angle. We use a uniform pdf for the
          time split, a step for stereo, and a triangular one for the rest. */
       if (stereo && N>2)
@@ -793,7 +849,7 @@
    } else if (stereo) {
       if (encode)
       {
-         inv = itheta > 8192;
+         inv = itheta > 8192 && !ctx->disable_inv;
          if (inv)
          {
             int j;
@@ -810,6 +866,9 @@
             inv = ec_dec_bit_logp(ec, 2);
       } else
          inv = 0;
+      /* inv flag override to avoid problems with downmixing. */
+      if (ctx->disable_inv)
+         inv = 0;
       itheta = 0;
    }
    qalloc = ec_tell_frac(ec) - tell;
@@ -845,11 +904,6 @@
 static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b,
       celt_norm *lowband_out)
 {
-#ifdef RESYNTH
-   int resynth = 1;
-#else
-   int resynth = !ctx->encode;
-#endif
    int c;
    int stereo;
    celt_norm *x = X;
@@ -874,7 +928,7 @@
          ctx->remaining_bits -= 1<<BITRES;
          b-=1<<BITRES;
       }
-      if (resynth)
+      if (ctx->resynth)
          x[0] = sign ? -NORM_SCALING : NORM_SCALING;
       x = Y;
    } while (++c<1+stereo);
@@ -899,11 +953,6 @@
    int B0=B;
    opus_val16 mid=0, side=0;
    unsigned cm=0;
-#ifdef RESYNTH
-   int resynth = 1;
-#else
-   int resynth = !ctx->encode;
-#endif
    celt_norm *Y=NULL;
    int encode;
    const CELTMode *m;
@@ -935,8 +984,7 @@
          fill = (fill&1)|(fill<<1);
       B = (B+1)>>1;
 
-      compute_theta(ctx, &sctx, X, Y, N, &b, B, B0,
-            LM, 0, &fill);
+      compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, LM, 0, &fill);
       imid = sctx.imid;
       iside = sctx.iside;
       delta = sctx.delta;
@@ -970,24 +1018,20 @@
       rebalance = ctx->remaining_bits;
       if (mbits >= sbits)
       {
-         cm = quant_partition(ctx, X, N, mbits, B,
-               lowband, LM,
+         cm = quant_partition(ctx, X, N, mbits, B, lowband, LM,
                MULT16_16_P15(gain,mid), fill);
          rebalance = mbits - (rebalance-ctx->remaining_bits);
          if (rebalance > 3<<BITRES && itheta!=0)
             sbits += rebalance - (3<<BITRES);
-         cm |= quant_partition(ctx, Y, N, sbits, B,
-               next_lowband2, LM,
+         cm |= quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
                MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
       } else {
-         cm = quant_partition(ctx, Y, N, sbits, B,
-               next_lowband2, LM,
+         cm = quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
                MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
          rebalance = sbits - (rebalance-ctx->remaining_bits);
          if (rebalance > 3<<BITRES && itheta!=16384)
             mbits += rebalance - (3<<BITRES);
-         cm |= quant_partition(ctx, X, N, mbits, B,
-               lowband, LM,
+         cm |= quant_partition(ctx, X, N, mbits, B, lowband, LM,
                MULT16_16_P15(gain,mid), fill);
       }
    } else {
@@ -1012,18 +1056,14 @@
          /* Finally do the actual quantization */
          if (encode)
          {
-            cm = alg_quant(X, N, K, spread, B, ec
-#ifdef RESYNTH
-                 , gain
-#endif
-                 );
+            cm = alg_quant(X, N, K, spread, B, ec, gain, ctx->resynth, ctx->arch);
          } else {
             cm = alg_unquant(X, N, K, spread, B, ec, gain);
          }
       } else {
          /* If there's no pulse, fill the band anyway */
          int j;
-         if (resynth)
+         if (ctx->resynth)
          {
             unsigned cm_mask;
             /* B can be as large as 16, so this shift might overflow an int on a
@@ -1080,11 +1120,6 @@
    int recombine=0;
    int longBlocks;
    unsigned cm=0;
-#ifdef RESYNTH
-   int resynth = 1;
-#else
-   int resynth = !ctx->encode;
-#endif
    int k;
    int encode;
    int tf_change;
@@ -1151,11 +1186,10 @@
          deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);
    }
 
-   cm = quant_partition(ctx, X, N, b, B, lowband,
-         LM, gain, fill);
+   cm = quant_partition(ctx, X, N, b, B, lowband, LM, gain, fill);
 
    /* This code is used by the decoder and by the resynthesis-enabled encoder */
-   if (resynth)
+   if (ctx->resynth)
    {
       /* Undo the sample reorganization going from time order to frequency order */
       if (B0>1)
@@ -1208,11 +1242,6 @@
    int inv = 0;
    opus_val16 mid=0, side=0;
    unsigned cm=0;
-#ifdef RESYNTH
-   int resynth = 1;
-#else
-   int resynth = !ctx->encode;
-#endif
    int mbits, sbits, delta;
    int itheta;
    int qalloc;
@@ -1232,8 +1261,7 @@
 
    orig_fill = fill;
 
-   compute_theta(ctx, &sctx, X, Y, N, &b, B, B,
-         LM, 1, &fill);
+   compute_theta(ctx, &sctx, X, Y, N, &b, B, B, LM, 1, &fill);
    inv = sctx.inv;
    imid = sctx.imid;
    iside = sctx.iside;
@@ -1281,13 +1309,13 @@
       sign = 1-2*sign;
       /* We use orig_fill here because we want to fold the side, but if
          itheta==16384, we'll have cleared the low bits of fill. */
-      cm = quant_band(ctx, x2, N, mbits, B, lowband,
-            LM, lowband_out, Q15ONE, lowband_scratch, orig_fill);
+      cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
+            lowband_scratch, orig_fill);
       /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
          and there's no need to worry about mixing with the other channel. */
       y2[0] = -sign*x2[1];
       y2[1] = sign*x2[0];
-      if (resynth)
+      if (ctx->resynth)
       {
          celt_norm tmp;
          X[0] = MULT16_16_Q15(mid, X[0]);
@@ -1314,38 +1342,32 @@
       {
          /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
             mid for folding later. */
-         cm = quant_band(ctx, X, N, mbits, B,
-               lowband, LM, lowband_out,
-               Q15ONE, lowband_scratch, fill);
+         cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
+               lowband_scratch, fill);
          rebalance = mbits - (rebalance-ctx->remaining_bits);
          if (rebalance > 3<<BITRES && itheta!=0)
             sbits += rebalance - (3<<BITRES);
 
          /* For a stereo split, the high bits of fill are always zero, so no
             folding will be done to the side. */
-         cm |= quant_band(ctx, Y, N, sbits, B,
-               NULL, LM, NULL,
-               side, NULL, fill>>B);
+         cm |= quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B);
       } else {
          /* For a stereo split, the high bits of fill are always zero, so no
             folding will be done to the side. */
-         cm = quant_band(ctx, Y, N, sbits, B,
-               NULL, LM, NULL,
-               side, NULL, fill>>B);
+         cm = quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B);
          rebalance = sbits - (rebalance-ctx->remaining_bits);
          if (rebalance > 3<<BITRES && itheta!=16384)
             mbits += rebalance - (3<<BITRES);
          /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
             mid for folding later. */
-         cm |= quant_band(ctx, X, N, mbits, B,
-               lowband, LM, lowband_out,
-               Q15ONE, lowband_scratch, fill);
+         cm |= quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
+               lowband_scratch, fill);
       }
    }
 
 
    /* This code is used by the decoder and by the resynthesis-enabled encoder */
-   if (resynth)
+   if (ctx->resynth)
    {
       if (N!=2)
          stereo_merge(X, Y, mid, N, ctx->arch);
@@ -1359,19 +1381,38 @@
    return cm;
 }
 
+static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm *norm2, int start, int M, int dual_stereo)
+{
+   int n1, n2;
+   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
+   n1 = M*(eBands[start+1]-eBands[start]);
+   n2 = M*(eBands[start+2]-eBands[start+1]);
+   /* Duplicate enough of the first band folding data to be able to fold the second band.
+      Copies no data for CELT-only mode. */
+   OPUS_COPY(&norm[n1], &norm[2*n1 - n2], n2-n1);
+   if (dual_stereo)
+      OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1);
+}
 
 void quant_all_bands(int encode, const CELTMode *m, int start, int end,
       celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks,
       const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
       int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
       opus_int32 balance, ec_ctx *ec, int LM, int codedBands,
-      opus_uint32 *seed, int arch)
+      opus_uint32 *seed, int complexity, int arch, int disable_inv)
 {
    int i;
    opus_int32 remaining_bits;
    const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
    celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;
    VARDECL(celt_norm, _norm);
+   VARDECL(celt_norm, _lowband_scratch);
+   VARDECL(celt_norm, X_save);
+   VARDECL(celt_norm, Y_save);
+   VARDECL(celt_norm, X_save2);
+   VARDECL(celt_norm, Y_save2);
+   VARDECL(celt_norm, norm_save2);
+   int resynth_alloc;
    celt_norm *lowband_scratch;
    int B;
    int M;
@@ -1379,10 +1420,11 @@
    int update_lowband = 1;
    int C = Y_ != NULL ? 2 : 1;
    int norm_offset;
+   int theta_rdo = encode && Y_!=NULL && !dual_stereo && complexity>=8;
 #ifdef RESYNTH
    int resynth = 1;
 #else
-   int resynth = !encode;
+   int resynth = !encode || theta_rdo;
 #endif
    struct band_ctx ctx;
    SAVE_STACK;
@@ -1395,9 +1437,24 @@
    ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);
    norm = _norm;
    norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;
-   /* We can use the last band as scratch space because we don't need that
-      scratch space for the last band. */
-   lowband_scratch = X_+M*eBands[m->nbEBands-1];
+
+   /* For decoding, we can use the last band as scratch space because we don't need that
+      scratch space for the last band and we don't care about the data there until we're
+      decoding the last band. */
+   if (encode && resynth)
+      resynth_alloc = M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]);
+   else
+      resynth_alloc = ALLOC_NONE;
+   ALLOC(_lowband_scratch, resynth_alloc, celt_norm);
+   if (encode && resynth)
+      lowband_scratch = _lowband_scratch;
+   else
+      lowband_scratch = X_+M*eBands[m->nbEBands-1];
+   ALLOC(X_save, resynth_alloc, celt_norm);
+   ALLOC(Y_save, resynth_alloc, celt_norm);
+   ALLOC(X_save2, resynth_alloc, celt_norm);
+   ALLOC(Y_save2, resynth_alloc, celt_norm);
+   ALLOC(norm_save2, resynth_alloc, celt_norm);
 
    lowband_offset = 0;
    ctx.bandE = bandE;
@@ -1408,6 +1465,11 @@
    ctx.seed = *seed;
    ctx.spread = spread;
    ctx.arch = arch;
+   ctx.disable_inv = disable_inv;
+   ctx.resynth = resynth;
+   ctx.theta_round = 0;
+   /* Avoid injecting noise in the first band on transients. */
+   ctx.avoid_split_noise = B > 1;
    for (i=start;i<end;i++)
    {
       opus_int32 tell;
@@ -1445,8 +1507,15 @@
          b = 0;
       }
 
+#ifdef ENABLE_UPDATE_DRAFT
+      if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0))
+            lowband_offset = i;
+      if (i == start+1)
+         special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
+#else
       if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
             lowband_offset = i;
+#endif
 
       tf_change = tf_res[i];
       ctx.tf_change = tf_change;
@@ -1457,7 +1526,7 @@
             Y = norm;
          lowband_scratch = NULL;
       }
-      if (i==end-1)
+      if (last && !theta_rdo)
          lowband_scratch = NULL;
 
       /* Get a conservative estimate of the collapse_mask's for the bands we're
@@ -1472,7 +1541,11 @@
          fold_start = lowband_offset;
          while(M*eBands[--fold_start] > effective_lowband+norm_offset);
          fold_end = lowband_offset-1;
+#ifdef ENABLE_UPDATE_DRAFT
+         while(++fold_end < i && M*eBands[fold_end] < effective_lowband+norm_offset+N);
+#else
          while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);
+#endif
          x_cm = y_cm = 0;
          fold_i = fold_start; do {
            x_cm |= collapse_masks[fold_i*C+0];
@@ -1505,13 +1578,77 @@
       } else {
          if (Y!=NULL)
          {
-            x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
-                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
-                        last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
+            if (theta_rdo && i < intensity)
+            {
+               ec_ctx ec_save, ec_save2;
+               struct band_ctx ctx_save, ctx_save2;
+               opus_val32 dist0, dist1;
+               unsigned cm, cm2;
+               int nstart_bytes, nend_bytes, save_bytes;
+               unsigned char *bytes_buf;
+               unsigned char bytes_save[1275];
+               opus_val16 w[2];
+               compute_channel_weights(bandE[i], bandE[i+m->nbEBands], w);
+               /* Make a copy. */
+               cm = x_cm|y_cm;
+               ec_save = *ec;
+               ctx_save = ctx;
+               OPUS_COPY(X_save, X, N);
+               OPUS_COPY(Y_save, Y, N);
+               /* Encode and round down. */
+               ctx.theta_round = -1;
+               x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
+                     effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
+                     last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm);
+               dist0 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch));
+
+               /* Save first result. */
+               cm2 = x_cm;
+               ec_save2 = *ec;
+               ctx_save2 = ctx;
+               OPUS_COPY(X_save2, X, N);
+               OPUS_COPY(Y_save2, Y, N);
+               if (!last)
+                  OPUS_COPY(norm_save2, norm+M*eBands[i]-norm_offset, N);
+               nstart_bytes = ec_save.offs;
+               nend_bytes = ec_save.storage;
+               bytes_buf = ec_save.buf+nstart_bytes;
+               save_bytes = nend_bytes-nstart_bytes;
+               OPUS_COPY(bytes_save, bytes_buf, save_bytes);
+
+               /* Restore */
+               *ec = ec_save;
+               ctx = ctx_save;
+               OPUS_COPY(X, X_save, N);
+               OPUS_COPY(Y, Y_save, N);
+               if (i == start+1)
+                  special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
+               /* Encode and round up. */
+               ctx.theta_round = 1;
+               x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
+                     effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
+                     last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm);
+               dist1 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch));
+               if (dist0 >= dist1) {
+                  x_cm = cm2;
+                  *ec = ec_save2;
+                  ctx = ctx_save2;
+                  OPUS_COPY(X, X_save2, N);
+                  OPUS_COPY(Y, Y_save2, N);
+                  if (!last)
+                     OPUS_COPY(norm+M*eBands[i]-norm_offset, norm_save2, N);
+                  OPUS_COPY(bytes_buf, bytes_save, save_bytes);
+               }
+            } else {
+               ctx.theta_round = 0;
+               x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
+                     effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
+                     last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
+            }
          } else {
             x_cm = quant_band(&ctx, X, N, b, B,
                   effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
-                        last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
+                  last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
          }
          y_cm = x_cm;
       }
@@ -1521,6 +1658,9 @@
 
       /* Update the folding position only as long as we have 1 bit/sample depth. */
       update_lowband = b>(N<<BITRES);
+      /* We only need to avoid noise on a split for the first band. After that, we
+         have folding. */
+      ctx.avoid_split_noise = 0;
    }
    *seed = ctx.seed;
 
diff --git a/celt/bands.h b/celt/bands.h
index e8bef4b..2488c18 100644
--- a/celt/bands.h
+++ b/celt/bands.h
@@ -36,12 +36,15 @@
 #include "entdec.h"
 #include "rate.h"
 
+opus_int16 bitexact_cos(opus_int16 x);
+int bitexact_log2tan(int isin,int icos);
+
 /** Compute the amplitude (sqrt energy) in each of the bands
  * @param m Mode data
  * @param X Spectrum
  * @param bandE Square root of the energy for each band (returned)
  */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM);
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch);
 
 /*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
 
@@ -105,7 +108,7 @@
       const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
       int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
       opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed,
-      int arch);
+      int complexity, int arch, int disable_inv);
 
 void anti_collapse(const CELTMode *m, celt_norm *X_,
       unsigned char *collapse_masks, int LM, int C, int size, int start,
diff --git a/celt/celt.c b/celt/celt.c
index b121c51..9ce2346 100644
--- a/celt/celt.c
+++ b/celt/celt.c
@@ -111,26 +111,31 @@
       t = MAC16_32_Q16(x[i], g10, x2);
       t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
       t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
+      t = SATURATE(t, SIG_SAT);
       y[i] = t;
       x4=SHL32(x[i-T+3],1);
       t = MAC16_32_Q16(x[i+1], g10, x1);
       t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
       t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
+      t = SATURATE(t, SIG_SAT);
       y[i+1] = t;
       x3=SHL32(x[i-T+4],1);
       t = MAC16_32_Q16(x[i+2], g10, x0);
       t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
       t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
+      t = SATURATE(t, SIG_SAT);
       y[i+2] = t;
       x2=SHL32(x[i-T+5],1);
       t = MAC16_32_Q16(x[i+3], g10, x4);
       t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
       t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
+      t = SATURATE(t, SIG_SAT);
       y[i+3] = t;
       x1=SHL32(x[i-T+6],1);
       t = MAC16_32_Q16(x[i+4], g10, x3);
       t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
       t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
+      t = SATURATE(t, SIG_SAT);
       y[i+4] = t;
    }
 #ifdef CUSTOM_MODES
@@ -141,6 +146,7 @@
       t = MAC16_32_Q16(x[i], g10, x2);
       t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
       t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
+      t = SATURATE(t, SIG_SAT);
       y[i] = t;
       x4=x3;
       x3=x2;
@@ -169,6 +175,7 @@
                + MULT16_32_Q15(g10,x2)
                + MULT16_32_Q15(g11,ADD32(x1,x3))
                + MULT16_32_Q15(g12,ADD32(x0,x4));
+      y[i] = SATURATE(y[i], SIG_SAT);
       x4=x3;
       x3=x2;
       x2=x1;
@@ -200,6 +207,10 @@
          OPUS_MOVE(y, x, N);
       return;
    }
+   /* When the gain is zero, T0 and/or T1 is set to zero. We need
+      to have then be at least 2 to avoid processing garbage data. */
+   T0 = IMAX(T0, COMBFILTER_MINPERIOD);
+   T1 = IMAX(T1, COMBFILTER_MINPERIOD);
    g00 = MULT16_16_P15(g0, gains[tapset0][0]);
    g01 = MULT16_16_P15(g0, gains[tapset0][1]);
    g02 = MULT16_16_P15(g0, gains[tapset0][2]);
@@ -225,6 +236,7 @@
                + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
                + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
                + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
+      y[i] = SATURATE(y[i], SIG_SAT);
       x4=x3;
       x3=x2;
       x2=x1;
@@ -244,11 +256,16 @@
 }
 #endif /* OVERRIDE_comb_filter */
 
+/* TF change table. Positive values mean better frequency resolution (longer
+   effective window), whereas negative values mean better time resolution
+   (shorter effective window). The second index is computed as:
+   4*isTransient + 2*tf_select + per_band_flag */
 const signed char tf_select_table[4][8] = {
-      {0, -1, 0, -1,    0,-1, 0,-1},
-      {0, -1, 0, -2,    1, 0, 1,-1},
-      {0, -2, 0, -3,    2, 0, 1,-1},
-      {0, -2, 0, -3,    3, 0, 1,-1},
+    /*isTransient=0     isTransient=1 */
+      {0, -1, 0, -1,    0,-1, 0,-1}, /* 2.5 ms */
+      {0, -1, 0, -2,    1, 0, 1,-1}, /* 5 ms */
+      {0, -2, 0, -3,    2, 0, 1,-1}, /* 10 ms */
+      {0, -2, 0, -3,    3, 0, 1,-1}, /* 20 ms */
 };
 
 
diff --git a/celt/celt.h b/celt/celt.h
index d1f7eb6..7017530 100644
--- a/celt/celt.h
+++ b/celt/celt.h
@@ -50,6 +50,8 @@
 #define CELTDecoder OpusCustomDecoder
 #define CELTMode OpusCustomMode
 
+#define LEAK_BANDS 19
+
 typedef struct {
    int valid;
    float tonality;
@@ -57,17 +59,25 @@
    float noisiness;
    float activity;
    float music_prob;
-   int        bandwidth;
-}AnalysisInfo;
+   float vad_prob;
+   int   bandwidth;
+   float activity_probability;
+   /* Store as Q6 char to save space. */
+   unsigned char leak_boost[LEAK_BANDS];
+} AnalysisInfo;
+
+typedef struct {
+   int signalType;
+   int offset;
+} SILKInfo;
 
 #define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
 
 #define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))
 
-/* Encoder/decoder Requests */
+#define __celt_check_silkinfo_ptr(ptr) ((ptr) + ((ptr) - (const SILKInfo*)(ptr)))
 
-/* Expose this option again when variable framesize actually works */
-#define OPUS_FRAMESIZE_VARIABLE              5010 /**< Optimize the frame size dynamically */
+/* Encoder/decoder Requests */
 
 
 #define CELT_SET_PREDICTION_REQUEST    10002
@@ -116,6 +126,9 @@
 #define OPUS_SET_ENERGY_MASK_REQUEST    10026
 #define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
 
+#define CELT_SET_SILK_INFO_REQUEST    10028
+#define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x)
+
 /* Encoder stuff */
 
 int celt_encoder_get_size(int channels);
diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c
index b978bb3..567d745 100644
--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -73,6 +73,7 @@
    int downsample;
    int start, end;
    int signalling;
+   int disable_inv;
    int arch;
 
    /* Everything beyond this point gets cleared on a reset */
@@ -163,6 +164,11 @@
    st->start = 0;
    st->end = st->mode->effEBands;
    st->signalling = 1;
+#ifdef ENABLE_UPDATE_DRAFT
+   st->disable_inv = channels == 1;
+#else
+   st->disable_inv = 0;
+#endif
    st->arch = opus_select_arch();
 
    opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
@@ -177,6 +183,36 @@
 }
 #endif /* CUSTOM_MODES */
 
+#ifndef CUSTOM_MODES
+/* Special case for stereo with no downsampling and no accumulation. This is
+   quite common and we can make it faster by processing both channels in the
+   same loop, reducing overhead due to the dependency loop in the IIR filter. */
+static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
+      celt_sig *mem)
+{
+   celt_sig * OPUS_RESTRICT x0;
+   celt_sig * OPUS_RESTRICT x1;
+   celt_sig m0, m1;
+   int j;
+   x0=in[0];
+   x1=in[1];
+   m0 = mem[0];
+   m1 = mem[1];
+   for (j=0;j<N;j++)
+   {
+      celt_sig tmp0, tmp1;
+      /* Add VERY_SMALL to x[] first to reduce dependency chain. */
+      tmp0 = x0[j] + VERY_SMALL + m0;
+      tmp1 = x1[j] + VERY_SMALL + m1;
+      m0 = MULT16_32_Q15(coef0, tmp0);
+      m1 = MULT16_32_Q15(coef0, tmp1);
+      pcm[2*j  ] = SCALEOUT(SIG2WORD16(tmp0));
+      pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
+   }
+   mem[0] = m0;
+   mem[1] = m1;
+}
+#endif
 
 #ifndef RESYNTH
 static
@@ -190,6 +226,14 @@
    opus_val16 coef0;
    VARDECL(celt_sig, scratch);
    SAVE_STACK;
+#ifndef CUSTOM_MODES
+   /* Short version for common case. */
+   if (downsample == 1 && C == 2 && !accum)
+   {
+      deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
+      return;
+   }
+#endif
 #ifndef FIXED_POINT
    (void)accum;
    celt_assert(accum==0);
@@ -225,7 +269,7 @@
          /* Shortcut for the standard (non-custom modes) case */
          for (j=0;j<N;j++)
          {
-            celt_sig tmp = x[j] + m + VERY_SMALL;
+            celt_sig tmp = x[j] + VERY_SMALL + m;
             m = MULT16_32_Q15(coef0, tmp);
             scratch[j] = tmp;
          }
@@ -246,7 +290,7 @@
          {
             for (j=0;j<N;j++)
             {
-               celt_sig tmp = x[j] + m + VERY_SMALL;
+               celt_sig tmp = x[j] + VERY_SMALL + m;
                m = MULT16_32_Q15(coef0, tmp);
                y[j*C] = SCALEOUT(SIG2WORD16(tmp));
             }
@@ -333,7 +377,7 @@
       denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
             downsample, silence);
       for (i=0;i<N;i++)
-         freq[i] = HALF32(ADD32(freq[i],freq2[i]));
+         freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
       for (b=0;b<B;b++)
          clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
    } else {
@@ -345,6 +389,12 @@
             clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
       } while (++c<CC);
    }
+   /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
+      or in the */
+   c=0; do {
+      for (i=0;i<N;i++)
+         out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
+   } while (++c<CC);
    RESTORE_STACK;
 }
 
@@ -506,10 +556,11 @@
    } else {
       /* Pitch-based PLC */
       const opus_val16 *window;
+      opus_val16 *exc;
       opus_val16 fade = Q15ONE;
       int pitch_index;
       VARDECL(opus_val32, etmp);
-      VARDECL(opus_val16, exc);
+      VARDECL(opus_val16, _exc);
 
       if (loss_count == 0)
       {
@@ -520,7 +571,8 @@
       }
 
       ALLOC(etmp, overlap, opus_val32);
-      ALLOC(exc, MAX_PERIOD, opus_val16);
+      ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
+      exc = _exc+LPC_ORDER;
       window = mode->window;
       c=0; do {
          opus_val16 decay;
@@ -561,6 +613,23 @@
 #endif
             }
             _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
+#ifdef FIXED_POINT
+         /* For fixed-point, apply bandwidth expansion until we can guarantee that
+            no overflow can happen in the IIR filter. This means:
+            32768*sum(abs(filter)) < 2^31 */
+         while (1) {
+            opus_val16 tmp=Q15ONE;
+            opus_val32 sum=QCONST16(1., SIG_SHIFT);
+            for (i=0;i<LPC_ORDER;i++)
+               sum += ABS16(lpc[c*LPC_ORDER+i]);
+            if (sum < 65535) break;
+            for (i=0;i<LPC_ORDER;i++)
+            {
+               tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
+               lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
+            }
+         }
+#endif
          }
          /* We want the excitation for 2 pitch periods in order to look for a
             decaying signal, but we can't get more than MAX_PERIOD. */
@@ -568,15 +637,14 @@
          /* Initialize the LPC history with the samples just before the start
             of the region for which we're computing the excitation. */
          {
-            opus_val16 lpc_mem[LPC_ORDER];
             for (i=0;i<LPC_ORDER;i++)
             {
-               lpc_mem[i] =
-                     ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
+               exc[MAX_PERIOD-exc_length-LPC_ORDER+i] =
+                     ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-LPC_ORDER+i], SIG_SHIFT);
             }
             /* Compute the excitation for exc_length samples before the loss. */
             celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
-                  exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem, st->arch);
+                  exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, st->arch);
          }
 
          /* Check if the waveform is decaying, and if so how fast.
@@ -630,9 +698,8 @@
             tmp = ROUND16(
                   buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
                   SIG_SHIFT);
-            S1 += SHR32(MULT16_16(tmp, tmp), 8);
+            S1 += SHR32(MULT16_16(tmp, tmp), 10);
          }
-
          {
             opus_val16 lpc_mem[LPC_ORDER];
             /* Copy the last decoded samples (prior to the overlap region) to
@@ -644,6 +711,10 @@
             celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
                   buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
                   lpc_mem, st->arch);
+#ifdef FIXED_POINT
+            for (i=0; i < extrapolation_len; i++)
+               buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT);
+#endif
          }
 
          /* Check if the synthesis energy is higher than expected, which can
@@ -654,7 +725,7 @@
             for (i=0;i<extrapolation_len;i++)
             {
                opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
-               S2 += SHR32(MULT16_16(tmp, tmp), 8);
+               S2 += SHR32(MULT16_16(tmp, tmp), 10);
             }
             /* This checks for an "explosion" in the synthesis. */
 #ifdef FIXED_POINT
@@ -979,7 +1050,8 @@
 
    quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
          NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
-         len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch);
+         len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
+         st->arch, st->disable_inv);
 
    if (anti_collapse_rsv > 0)
    {
@@ -1234,6 +1306,26 @@
          *value=st->rng;
       }
       break;
+      case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
+      {
+          opus_int32 value = va_arg(ap, opus_int32);
+          if(value<0 || value>1)
+          {
+             goto bad_arg;
+          }
+          st->disable_inv = value;
+      }
+      break;
+      case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
+      {
+          opus_int32 *value = va_arg(ap, opus_int32*);
+          if (!value)
+          {
+             goto bad_arg;
+          }
+          *value = st->disable_inv;
+      }
+      break;
       default:
          goto bad_request;
    }
diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c
index 3ee7a4d..053e5a3 100644
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -73,8 +73,8 @@
    int constrained_vbr;      /* If zero, VBR can do whatever it likes with the rate */
    int loss_rate;
    int lsb_depth;
-   int variable_duration;
    int lfe;
+   int disable_inv;
    int arch;
 
    /* Everything beyond this point gets cleared on a reset */
@@ -98,6 +98,7 @@
 #endif
    int consec_transient;
    AnalysisInfo analysis;
+   SILKInfo silk_info;
 
    opus_val32 preemph_memE[2];
    opus_val32 preemph_memD[2];
@@ -123,6 +124,7 @@
    /* opus_val16 oldBandE[],     Size = channels*mode->nbEBands */
    /* opus_val16 oldLogE[],      Size = channels*mode->nbEBands */
    /* opus_val16 oldLogE2[],     Size = channels*mode->nbEBands */
+   /* opus_val16 energyError[],  Size = channels*mode->nbEBands */
 };
 
 int celt_encoder_get_size(int channels)
@@ -136,9 +138,10 @@
    int size = sizeof(struct CELTEncoder)
          + (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]; */
+         + 4*channels*mode->nbEBands*sizeof(opus_val16);  /* opus_val16 oldBandE[channels*mode->nbEBands]; */
                                                           /* opus_val16 oldLogE[channels*mode->nbEBands]; */
                                                           /* opus_val16 oldLogE2[channels*mode->nbEBands]; */
+                                                          /* opus_val16 energyError[channels*mode->nbEBands]; */
    return size;
 }
 
@@ -178,7 +181,6 @@
    st->start = 0;
    st->end = st->mode->effEBands;
    st->signalling = 1;
-
    st->arch = arch;
 
    st->constrained_vbr = 1;
@@ -223,7 +225,8 @@
 
 
 static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,
-                              opus_val16 *tf_estimate, int *tf_chan)
+                              opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients,
+                              int *weak_transient)
 {
    int i;
    VARDECL(opus_val16, tmp);
@@ -233,6 +236,12 @@
    int c;
    opus_val16 tf_max;
    int len2;
+   /* Forward masking: 6.7 dB/ms. */
+#ifdef FIXED_POINT
+   int forward_shift = 4;
+#else
+   opus_val16 forward_decay = QCONST16(.0625f,15);
+#endif
    /* Table of 6*64/x, trained on real data to minimize the average error */
    static const unsigned char inv_table[128] = {
          255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25,
@@ -247,6 +256,19 @@
    SAVE_STACK;
    ALLOC(tmp, len, opus_val16);
 
+   *weak_transient = 0;
+   /* For lower bitrates, let's be more conservative and have a forward masking
+      decay of 3.3 dB/ms. This avoids having to code transients at very low
+      bitrate (mostly for hybrid), which can result in unstable energy and/or
+      partial collapse. */
+   if (allow_weak_transients)
+   {
+#ifdef FIXED_POINT
+      forward_shift = 5;
+#else
+      forward_decay = QCONST16(.03125f,15);
+#endif
+   }
    len2=len/2;
    for (c=0;c<C;c++)
    {
@@ -269,7 +291,7 @@
          mem0 = mem1 + y - 2*x;
          mem1 = x - .5f*y;
 #endif
-         tmp[i] = EXTRACT16(SHR32(y,2));
+         tmp[i] = SROUND16(y, 2);
          /*printf("%f ", tmp[i]);*/
       }
       /*printf("\n");*/
@@ -280,7 +302,7 @@
       /* Normalize tmp to max range */
       {
          int shift=0;
-         shift = 14-celt_ilog2(1+celt_maxabs16(tmp, len));
+         shift = 14-celt_ilog2(MAX16(1, celt_maxabs16(tmp, len)));
          if (shift!=0)
          {
             for (i=0;i<len;i++)
@@ -299,9 +321,9 @@
          mean += x2;
 #ifdef FIXED_POINT
          /* FIXME: Use PSHR16() instead */
-         tmp[i] = mem0 + PSHR32(x2-mem0,4);
+         tmp[i] = mem0 + PSHR32(x2-mem0,forward_shift);
 #else
-         tmp[i] = mem0 + MULT16_16_P15(QCONST16(.0625f,15),x2-mem0);
+         tmp[i] = mem0 + MULT16_16_P15(forward_decay,x2-mem0);
 #endif
          mem0 = tmp[i];
       }
@@ -311,6 +333,7 @@
       /* Backward pass to compute the pre-echo threshold */
       for (i=len2-1;i>=0;i--)
       {
+         /* Backward masking: 13.9 dB/ms. */
 #ifdef FIXED_POINT
          /* FIXME: Use PSHR16() instead */
          tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3);
@@ -359,7 +382,12 @@
       }
    }
    is_transient = mask_metric>200;
-
+   /* For low bitrates, define "weak transients" that need to be
+      handled differently to avoid partial collapse. */
+   if (allow_weak_transients && is_transient && mask_metric<600) {
+      is_transient = 0;
+      *weak_transient = 1;
+   }
    /* Arbitrary metric for VBR boost */
    tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42);
    /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */
@@ -549,7 +577,7 @@
 
 static int tf_analysis(const CELTMode *m, int len, int isTransient,
       int *tf_res, int lambda, celt_norm *X, int N0, int LM,
-      int *tf_sum, opus_val16 tf_estimate, int tf_chan)
+      opus_val16 tf_estimate, int tf_chan)
 {
    int i;
    VARDECL(int, metric);
@@ -574,7 +602,6 @@
    ALLOC(path0, len, int);
    ALLOC(path1, len, int);
 
-   *tf_sum = 0;
    for (i=0;i<len;i++)
    {
       int k, N;
@@ -629,7 +656,6 @@
          metric[i] = 2*best_level;
       else
          metric[i] = -2*best_level;
-      *tf_sum += (isTransient ? LM : 0) - metric[i]/2;
       /* For bands that can't be split to -1, set the metric to the half-way point to avoid
          biasing the decision */
       if (narrow && (metric[i]==0 || metric[i]==-2*LM))
@@ -754,7 +780,7 @@
 static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
       const opus_val16 *bandLogE, int end, int LM, int C, int N0,
       AnalysisInfo *analysis, opus_val16 *stereo_saving, opus_val16 tf_estimate,
-      int intensity, opus_val16 surround_trim, int arch)
+      int intensity, opus_val16 surround_trim, opus_int32 equiv_rate, int arch)
 {
    int i;
    opus_val32 diff=0;
@@ -762,6 +788,14 @@
    int trim_index;
    opus_val16 trim = QCONST16(5.f, 8);
    opus_val16 logXC, logXC2;
+   /* At low bitrate, reducing the trim seems to help. At higher bitrates, it's less
+      clear what's best, so we're keeping it as it was before, at least for now. */
+   if (equiv_rate < 64000) {
+      trim = QCONST16(4.f, 8);
+   } else if (equiv_rate < 80000) {
+      opus_int32 frac = (equiv_rate-64000) >> 10;
+      trim = QCONST16(4.f, 8) + QCONST16(1.f/16.f, 8)*frac;
+   }
    if (C==2)
    {
       opus_val16 sum = 0; /* Q10 */
@@ -809,7 +843,7 @@
    } while (++c<C);
    diff /= C*(end-1);
    /*printf("%f\n", diff);*/
-   trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
+   trim -= MAX32(-QCONST16(2.f, 8), MIN32(QCONST16(2.f, 8), SHR32(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
    trim -= SHR16(surround_trim, DB_SHIFT-8);
    trim -= 2*SHR16(tf_estimate, 14-8);
 #ifndef DISABLE_FLOAT_API
@@ -930,7 +964,7 @@
 static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2,
       int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN,
       int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM,
-      int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc)
+      int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc, AnalysisInfo *analysis)
 {
    int i, c;
    opus_int32 tot_boost=0;
@@ -1020,14 +1054,26 @@
       }
       for (i=start;i<end;i++)
       {
-         int width;
-         int boost;
-         int boost_bits;
-
          if (i<8)
             follower[i] *= 2;
          if (i>=12)
             follower[i] = HALF16(follower[i]);
+      }
+#ifdef DISABLE_FLOAT_API
+      (void)analysis;
+#else
+      if (analysis->valid)
+      {
+         for (i=start;i<IMIN(LEAK_BANDS, end);i++)
+            follower[i] = follower[i] +  QCONST16(1.f/64.f, DB_SHIFT)*analysis->leak_boost[i];
+      }
+#endif
+      for (i=start;i<end;i++)
+      {
+         int width;
+         int boost;
+         int boost_bits;
+
          follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT));
 
          width = C*(eBands[i+1]-eBands[i])<<LM;
@@ -1042,11 +1088,11 @@
             boost = (int)SHR32(EXTEND32(follower[i])*width/6,DB_SHIFT);
             boost_bits = boost*6<<BITRES;
          }
-         /* For CBR and non-transient CVBR frames, limit dynalloc to 1/4 of the bits */
+         /* For CBR and non-transient CVBR frames, limit dynalloc to 2/3 of the bits */
          if ((!vbr || (constrained_vbr&&!isTransient))
-               && (tot_boost+boost_bits)>>BITRES>>3 > effectiveBytes/4)
+               && (tot_boost+boost_bits)>>BITRES>>3 > 2*effectiveBytes/3)
          {
-            opus_int32 cap = ((effectiveBytes/4)<<BITRES<<3);
+            opus_int32 cap = ((2*effectiveBytes/3)<<BITRES<<3);
             offsets[i] = cap-tot_boost;
             tot_boost = cap;
             break;
@@ -1193,7 +1239,7 @@
       int LM, opus_int32 bitrate, int lastCodedBands, int C, int intensity,
       int constrained_vbr, opus_val16 stereo_saving, int tot_boost,
       opus_val16 tf_estimate, int pitch_change, opus_val16 maxDepth,
-      int variable_duration, int lfe, int has_surround_mask, opus_val16 surround_masking,
+      int lfe, int has_surround_mask, opus_val16 surround_masking,
       opus_val16 temporal_vbr)
 {
    /* The target rate in 8th bits per frame */
@@ -1235,10 +1281,9 @@
                       SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8));
    }
    /* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */
-   target += tot_boost-(16<<LM);
+   target += tot_boost-(19<<LM);
    /* Apply transient boost, compensating for average boost. */
-   tf_calibration = variable_duration==OPUS_FRAMESIZE_VARIABLE ?
-                    QCONST16(0.02f,14) : QCONST16(0.04f,14);
+   tf_calibration = QCONST16(0.044f,14);
    target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1);
 
 #ifndef DISABLE_FLOAT_API
@@ -1249,7 +1294,7 @@
       float tonal;
 
       /* Tonality boost (compensating for the average). */
-      tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f;
+      tonal = MAX16(0.f,analysis->tonality-.15f)-0.12f;
       tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal);
       if (pitch_change)
          tonal_target +=  (opus_int32)((coded_bins<<BITRES)*.8f);
@@ -1279,21 +1324,11 @@
       /*printf("%f %d\n", maxDepth, floor_depth);*/
    }
 
-   if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000))
+   /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate
+      for long. Needs tuning. */
+   if ((!has_surround_mask||lfe) && constrained_vbr)
    {
-      opus_val16 rate_factor = Q15ONE;
-      if (bitrate < 64000)
-      {
-#ifdef FIXED_POINT
-         rate_factor = MAX16(0,(bitrate-32000));
-#else
-         rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000));
-#endif
-      }
-      if (constrained_vbr)
-         rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15));
-      target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target);
-
+      target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target);
    }
 
    if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14))
@@ -1331,7 +1366,7 @@
    VARDECL(int, tf_res);
    VARDECL(unsigned char, collapse_masks);
    celt_sig *prefilter_mem;
-   opus_val16 *oldBandE, *oldLogE, *oldLogE2;
+   opus_val16 *oldBandE, *oldLogE, *oldLogE2, *energyError;
    int shortBlocks=0;
    int isTransient=0;
    const int CC = st->channels;
@@ -1343,7 +1378,6 @@
    int end;
    int effEnd;
    int codedBands;
-   int tf_sum;
    int alloc_trim;
    int pitch_index=COMBFILTER_MINPERIOD;
    opus_val16 gain1 = 0;
@@ -1355,6 +1389,7 @@
    opus_int32 total_boost;
    opus_int32 balance;
    opus_int32 tell;
+   opus_int32 tell0_frac;
    int prefilter_tapset=0;
    int pf_on;
    int anti_collapse_rsv;
@@ -1376,7 +1411,9 @@
    opus_val16 surround_masking=0;
    opus_val16 temporal_vbr=0;
    opus_val16 surround_trim = 0;
-   opus_int32 equiv_rate = 510000;
+   opus_int32 equiv_rate;
+   int hybrid;
+   int weak_transient = 0;
    VARDECL(opus_val16, surround_dynalloc);
    ALLOC_STACK;
 
@@ -1386,6 +1423,7 @@
    eBands = mode->eBands;
    start = st->start;
    end = st->end;
+   hybrid = start != 0;
    tf_estimate = 0;
    if (nbCompressedBytes<2 || pcm==NULL)
    {
@@ -1409,12 +1447,14 @@
    oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD));
    oldLogE = oldBandE + CC*nbEBands;
    oldLogE2 = oldLogE + CC*nbEBands;
+   energyError = oldLogE2 + CC*nbEBands;
 
    if (enc==NULL)
    {
-      tell=1;
+      tell0_frac=tell=1;
       nbFilledBytes=0;
    } else {
+      tell0_frac=tell=ec_tell_frac(enc);
       tell=ec_tell(enc);
       nbFilledBytes=(tell+4)>>3;
    }
@@ -1467,10 +1507,11 @@
       if (st->bitrate!=OPUS_BITRATE_MAX)
          nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
                (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));
-      effectiveBytes = nbCompressedBytes;
+      effectiveBytes = nbCompressedBytes - nbFilledBytes;
    }
+   equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50);
    if (st->bitrate != OPUS_BITRATE_MAX)
-      equiv_rate = st->bitrate - (40*C+20)*((400>>LM) - 50);
+      equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50));
 
    if (enc==NULL)
    {
@@ -1558,8 +1599,8 @@
    {
       int enabled;
       int qg;
-      enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && start==0 && !silence && !st->disable_pf
-            && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE);
+      enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && !hybrid && !silence && !st->disable_pf
+            && st->complexity >= 5;
 
       prefilter_tapset = st->tapset_decision;
       pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes);
@@ -1568,7 +1609,7 @@
          pitch_change = 1;
       if (pf_on==0)
       {
-         if(start==0 && tell+16<=total_bits)
+         if(!hybrid && tell+16<=total_bits)
             ec_enc_bit_logp(enc, 0, 1);
       } else {
          /*This block is not gated by a total bits check only because
@@ -1589,8 +1630,12 @@
    shortBlocks = 0;
    if (st->complexity >= 1 && !st->lfe)
    {
+      /* Reduces the likelihood of energy instability on fricatives at low bitrate
+         in hybrid mode. It seems like we still want to have real transients on vowels
+         though (small SILK quantization offset value). */
+      int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.offset >= 100;
       isTransient = transient_analysis(in, N+overlap, CC,
-            &tf_estimate, &tf_chan);
+            &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient);
    }
    if (LM>0 && ec_tell(enc)+3<=total_bits)
    {
@@ -1610,7 +1655,7 @@
    if (secondMdct)
    {
       compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch);
-      compute_band_energies(mode, freq, bandE, effEnd, C, LM);
+      compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
       amp2Log2(mode, effEnd, end, bandE, bandLogE2, C);
       for (i=0;i<C*nbEBands;i++)
          bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));
@@ -1619,7 +1664,7 @@
    compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
    if (CC==2&&C==1)
       tf_chan = 0;
-   compute_band_energies(mode, freq, bandE, effEnd, C, LM);
+   compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
 
    if (st->lfe)
    {
@@ -1634,7 +1679,7 @@
    ALLOC(surround_dynalloc, C*nbEBands, opus_val16);
    OPUS_CLEAR(surround_dynalloc, end);
    /* This computes how much masking takes place between surround channels */
-   if (start==0&&st->energy_mask&&!st->lfe)
+   if (!hybrid&&st->energy_mask&&!st->lfe)
    {
       int mask_end;
       int midband;
@@ -1736,14 +1781,14 @@
 
    /* Last chance to catch any transient we might have missed in the
       time-domain analysis */
-   if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe)
+   if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe && !hybrid)
    {
       if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C))
       {
          isTransient = 1;
          shortBlocks = M;
          compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
-         compute_band_energies(mode, freq, bandE, effEnd, C, LM);
+         compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
          amp2Log2(mode, effEnd, end, bandE, bandLogE, C);
          /* Compensate for the scaling of short vs long mdcts */
          for (i=0;i<C*nbEBands;i++)
@@ -1762,29 +1807,47 @@
 
    ALLOC(tf_res, nbEBands, int);
    /* Disable variable tf resolution for hybrid and at very low bitrate */
-   if (effectiveBytes>=15*C && start==0 && st->complexity>=2 && !st->lfe)
+   if (effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe)
    {
       int lambda;
-      if (effectiveBytes<40)
-         lambda = 12;
-      else if (effectiveBytes<60)
-         lambda = 6;
-      else if (effectiveBytes<100)
-         lambda = 4;
-      else
-         lambda = 3;
-      lambda*=2;
-      tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, &tf_sum, tf_estimate, tf_chan);
+      lambda = IMAX(5, 1280/effectiveBytes + 2);
+      tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan);
       for (i=effEnd;i<end;i++)
          tf_res[i] = tf_res[effEnd-1];
+   } else if (hybrid && weak_transient)
+   {
+      /* For weak transients, we rely on the fact that improving time resolution using
+         TF on a long window is imperfect and will not result in an energy collapse at
+         low bitrate. */
+      for (i=0;i<end;i++)
+         tf_res[i] = 1;
+      tf_select=0;
+   } else if (hybrid && effectiveBytes<15)
+   {
+      /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */
+      for (i=0;i<end;i++)
+         tf_res[i] = 0;
+      tf_select=isTransient;
    } else {
-      tf_sum = 0;
       for (i=0;i<end;i++)
          tf_res[i] = isTransient;
       tf_select=0;
    }
 
    ALLOC(error, C*nbEBands, opus_val16);
+   c=0;
+   do {
+      for (i=start;i<end;i++)
+      {
+         /* When the energy is stable, slightly bias energy quantization towards
+            the previous error to make the gain more stable (a constant offset is
+            better than fluctuations). */
+         if (ABS32(SUB32(bandLogE[i+c*nbEBands], oldBandE[i+c*nbEBands])) < QCONST16(2.f, DB_SHIFT))
+         {
+            bandLogE[i+c*nbEBands] -= MULT16_16_Q15(energyError[i+c*nbEBands], QCONST16(0.25f, 15));
+         }
+      }
+   } while (++c < C);
    quant_coarse_energy(mode, start, end, effEnd, bandLogE,
          oldBandE, total_bits, error, enc,
          C, LM, nbAvailableBytes, st->force_intra,
@@ -1798,7 +1861,15 @@
       {
          st->tapset_decision = 0;
          st->spread_decision = SPREAD_NORMAL;
-      } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || start != 0)
+      } else if (hybrid)
+      {
+         if (st->complexity == 0)
+            st->spread_decision = SPREAD_NONE;
+         else if (isTransient)
+            st->spread_decision = SPREAD_NORMAL;
+         else
+            st->spread_decision = SPREAD_AGGRESSIVE;
+      } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
       {
          if (st->complexity == 0)
             st->spread_decision = SPREAD_NONE;
@@ -1834,7 +1905,7 @@
 
    maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets,
          st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,
-         eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc);
+         eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis);
    /* For LFE, everything interesting is in the first band */
    if (st->lfe)
       offsets[0] = IMIN(8, effectiveBytes/3);
@@ -1896,12 +1967,15 @@
    alloc_trim = 5;
    if (tell+(6<<BITRES) <= total_bits - total_boost)
    {
-      if (st->lfe)
+      if (start > 0 || st->lfe)
+      {
+         st->stereo_saving = 0;
          alloc_trim = 5;
-      else
+      } else {
          alloc_trim = alloc_trim_analysis(mode, X, bandLogE,
             end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate,
-            st->intensity, surround_trim, st->arch);
+            st->intensity, surround_trim, equiv_rate, st->arch);
+      }
       ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
       tell = ec_tell_frac(enc);
    }
@@ -1919,17 +1993,36 @@
      /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms.
         The CELT allocator will just not be able to use more than that anyway. */
      nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));
-     base_target = vbr_rate - ((40*C+20)<<BITRES);
+     if (!hybrid)
+     {
+        base_target = vbr_rate - ((40*C+20)<<BITRES);
+     } else {
+        base_target = IMAX(0, vbr_rate - ((9*C+4)<<BITRES));
+     }
 
      if (st->constrained_vbr)
         base_target += (st->vbr_offset>>lm_diff);
 
-     target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
+     if (!hybrid)
+     {
+        target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
            st->lastCodedBands, C, st->intensity, st->constrained_vbr,
            st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth,
-           st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking,
+           st->lfe, st->energy_mask!=NULL, surround_masking,
            temporal_vbr);
-
+     } else {
+        target = base_target;
+        /* Tonal frames (offset<100) need more bits than noisy (offset>100) ones. */
+        if (st->silk_info.offset < 100) target += 12 << BITRES >> (3-LM);
+        if (st->silk_info.offset > 100) target -= 18 << BITRES >> (3-LM);
+        /* Boosting bitrate on transients and vowels with significant temporal
+           spikes. */
+        target += (opus_int32)MULT16_16_Q14(tf_estimate-QCONST16(.25f,14), (50<<BITRES));
+        /* If we have a strong transient, let's make sure it has enough bits to code
+           the first two bands, so that it can use folding rather than noise. */
+        if (tf_estimate > QCONST16(.7f,14))
+           target = IMAX(target, 50<<BITRES);
+     }
      /* The current offset is removed from the target and the space used
         so far is added*/
      target=target+tell;
@@ -1937,11 +2030,16 @@
          result in the encoder running out of bits.
         The margin of 2 bytes ensures that none of the bust-prevention logic
          in the decoder will have triggered so far. */
-     min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes;
+     min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2;
+     /* Take into account the 37 bits we need to have left in the packet to
+        signal a redundant frame in hybrid mode. Creating a shorter packet would
+        create an entropy coder desync. */
+     if (hybrid)
+        min_allowed = IMAX(min_allowed, (tell0_frac+(37<<BITRES)+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3));
 
      nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
      nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
-     nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
+     nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
 
      /* By how much did we "miss" the target on that frame */
      delta = target - vbr_rate;
@@ -1988,7 +2086,7 @@
         st->vbr_reservoir = 0;
         /*printf ("+%d\n", adjust);*/
      }
-     nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
+     nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
      /*printf("%d\n", nbCompressedBytes*50*8);*/
      /* This moves the raw bits to take into account the new compressed size */
      ec_enc_shrink(enc, nbCompressedBytes);
@@ -2038,7 +2136,7 @@
    quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
          bandE, pulses, shortBlocks, st->spread_decision,
          dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv,
-         balance, enc, LM, codedBands, &st->rng, st->arch);
+         balance, enc, LM, codedBands, &st->rng, st->complexity, st->arch, st->disable_inv);
 
    if (anti_collapse_rsv > 0)
    {
@@ -2049,6 +2147,14 @@
       ec_enc_bits(enc, anti_collapse_on, 1);
    }
    quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
+   OPUS_CLEAR(energyError, nbEBands*CC);
+   c=0;
+   do {
+      for (i=start;i<end;i++)
+      {
+         energyError[i+c*nbEBands] = MAX16(-QCONST16(0.5f, 15), MIN16(QCONST16(0.5f, 15), error[i+c*nbEBands]));
+      }
+   } while (++c < C);
 
    if (silence)
    {
@@ -2321,10 +2427,24 @@
           *value=st->lsb_depth;
       }
       break;
-      case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
+      case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
       {
           opus_int32 value = va_arg(ap, opus_int32);
-          st->variable_duration = value;
+          if(value<0 || value>1)
+          {
+             goto bad_arg;
+          }
+          st->disable_inv = value;
+      }
+      break;
+      case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
+      {
+          opus_int32 *value = va_arg(ap, opus_int32*);
+          if (!value)
+          {
+             goto bad_arg;
+          }
+          *value = st->disable_inv;
       }
       break;
       case OPUS_RESET_STATE:
@@ -2368,6 +2488,13 @@
             OPUS_COPY(&st->analysis, info, 1);
       }
       break;
+      case CELT_SET_SILK_INFO_REQUEST:
+      {
+         SILKInfo *info = va_arg(ap, SILKInfo *);
+         if (info)
+            OPUS_COPY(&st->silk_info, info, 1);
+      }
+      break;
       case CELT_GET_MODE_REQUEST:
       {
          const CELTMode ** value = va_arg(ap, const CELTMode**);
diff --git a/celt/celt_lpc.c b/celt/celt_lpc.c
index b410a21..57bc5f3 100644
--- a/celt/celt_lpc.c
+++ b/celt/celt_lpc.c
@@ -89,58 +89,40 @@
 
 
 void celt_fir_c(
-         const opus_val16 *_x,
+         const opus_val16 *x,
          const opus_val16 *num,
-         opus_val16 *_y,
+         opus_val16 *y,
          int N,
          int ord,
-         opus_val16 *mem,
          int arch)
 {
    int i,j;
    VARDECL(opus_val16, rnum);
-   VARDECL(opus_val16, x);
    SAVE_STACK;
 
    ALLOC(rnum, ord, opus_val16);
-   ALLOC(x, N+ord, opus_val16);
    for(i=0;i<ord;i++)
       rnum[i] = num[ord-i-1];
-   for(i=0;i<ord;i++)
-      x[i] = mem[ord-i-1];
-   for (i=0;i<N;i++)
-      x[i+ord]=_x[i];
-   for(i=0;i<ord;i++)
-      mem[i] = _x[N-i-1];
-#ifdef SMALL_FOOTPRINT
-   (void)arch;
-   for (i=0;i<N;i++)
-   {
-      opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
-      for (j=0;j<ord;j++)
-      {
-         sum = MAC16_16(sum,rnum[j],x[i+j]);
-      }
-      _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
-   }
-#else
    for (i=0;i<N-3;i+=4)
    {
-      opus_val32 sum[4]={0,0,0,0};
-      xcorr_kernel(rnum, x+i, sum, ord, arch);
-      _y[i  ] = SATURATE16(ADD32(EXTEND32(_x[i  ]), PSHR32(sum[0], SIG_SHIFT)));
-      _y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT)));
-      _y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT)));
-      _y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT)));
+      opus_val32 sum[4];
+      sum[0] = SHL32(EXTEND32(x[i  ]), SIG_SHIFT);
+      sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT),
+      sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
+      sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
+      xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
+      y[i  ] = ROUND16(sum[0], SIG_SHIFT);
+      y[i+1] = ROUND16(sum[1], SIG_SHIFT);
+      y[i+2] = ROUND16(sum[2], SIG_SHIFT);
+      y[i+3] = ROUND16(sum[3], SIG_SHIFT);
    }
    for (;i<N;i++)
    {
-      opus_val32 sum = 0;
+      opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
       for (j=0;j<ord;j++)
-         sum = MAC16_16(sum,rnum[j],x[i+j]);
-      _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
+         sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
+      y[i] = ROUND16(sum, SIG_SHIFT);
    }
-#endif
    RESTORE_STACK;
 }
 
@@ -166,7 +148,7 @@
       {
          mem[j]=mem[j-1];
       }
-      mem[0] = ROUND16(sum,SIG_SHIFT);
+      mem[0] = SROUND16(sum, SIG_SHIFT);
       _y[i] = sum;
    }
 #else
@@ -195,20 +177,20 @@
       xcorr_kernel(rden, y+i, sum, ord, arch);
 
       /* Patch up the result to compensate for the fact that this is an IIR */
-      y[i+ord  ] = -ROUND16(sum[0],SIG_SHIFT);
+      y[i+ord  ] = -SROUND16(sum[0],SIG_SHIFT);
       _y[i  ] = sum[0];
       sum[1] = MAC16_16(sum[1], y[i+ord  ], den[0]);
-      y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);
+      y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
       _y[i+1] = sum[1];
       sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
       sum[2] = MAC16_16(sum[2], y[i+ord  ], den[1]);
-      y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);
+      y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
       _y[i+2] = sum[2];
 
       sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
       sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
       sum[3] = MAC16_16(sum[3], y[i+ord  ], den[2]);
-      y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);
+      y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
       _y[i+3] = sum[3];
    }
    for (;i<N;i++)
@@ -216,7 +198,7 @@
       opus_val32 sum = _x[i];
       for (j=0;j<ord;j++)
          sum -= MULT16_16(rden[j],y[i+j]);
-      y[i+ord] = ROUND16(sum,SIG_SHIFT);
+      y[i+ord] = SROUND16(sum,SIG_SHIFT);
       _y[i] = sum;
    }
    for(i=0;i<ord;i++)
diff --git a/celt/celt_lpc.h b/celt/celt_lpc.h
index 323459e..a4c5fd6 100644
--- a/celt/celt_lpc.h
+++ b/celt/celt_lpc.h
@@ -45,12 +45,11 @@
          opus_val16 *y,
          int N,
          int ord,
-         opus_val16 *mem,
          int arch);
 
 #if !defined(OVERRIDE_CELT_FIR)
-#define celt_fir(x, num, y, N, ord, mem, arch) \
-    (celt_fir_c(x, num, y, N, ord, mem, arch))
+#define celt_fir(x, num, y, N, ord, arch) \
+    (celt_fir_c(x, num, y, N, ord, arch))
 #endif
 
 void celt_iir(const opus_val32 *x,
diff --git a/celt/dump_modes/dump_modes_arm_ne10.c b/celt/dump_modes/dump_modes_arm_ne10.c
index 47578cd..828e7b9 100644
--- a/celt/dump_modes/dump_modes_arm_ne10.c
+++ b/celt/dump_modes/dump_modes_arm_ne10.c
@@ -60,7 +60,7 @@
       fprintf(file, " %d %d",mode->Fs,mode->shortMdctSize*mode->nbShortMdcts);
    }
    fprintf(file, "\n * It contains static definitions for some pre-defined modes. */\n");
-   fprintf(file, "#include <NE10_init.h>\n\n");
+   fprintf(file, "#include <NE10_types.h>\n\n");
 }
 
 void dump_modes_arch_finalize()
diff --git a/celt/fixed_debug.h b/celt/fixed_debug.h
index d28227f..f435295 100644
--- a/celt/fixed_debug.h
+++ b/celt/fixed_debug.h
@@ -59,6 +59,14 @@
 #define SHR(a,b) SHR32(a,b)
 #define PSHR(a,b) PSHR32(a,b)
 
+/** Add two 32-bit values, ignore any overflows */
+#define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
+/** Subtract two 32-bit values, ignore any overflows */
+#define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
+/* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
+/** Negate 32-bit value, ignore any overflows */
+#define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(0-(opus_uint32)(a)))
+
 static OPUS_INLINE short NEG16(int x)
 {
    int res;
@@ -227,12 +235,11 @@
 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
 
 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
+#define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
+
 #define HALF16(x)  (SHR16(x,1))
 #define HALF32(x)  (SHR32(x,1))
 
-//#define SHR(a,shift) ((a) >> (shift))
-//#define SHL(a,shift) ((a) << (shift))
-
 #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
 static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
 {
diff --git a/celt/fixed_generic.h b/celt/fixed_generic.h
index 1cfd6d6..5f4abda 100644
--- a/celt/fixed_generic.h
+++ b/celt/fixed_generic.h
@@ -104,6 +104,9 @@
 
 /** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
 #define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
+/** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */
+#define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767));
+
 /** Divide by two */
 #define HALF16(x)  (SHR16(x,1))
 #define HALF32(x)  (SHR32(x,1))
@@ -117,6 +120,14 @@
 /** Subtract two 32-bit values */
 #define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))
 
+/** Add two 32-bit values, ignore any overflows */
+#define ADD32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
+/** Subtract two 32-bit values, ignore any overflows */
+#define SUB32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
+/* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
+/** Negate 32-bit value, ignore any overflows */
+#define NEG32_ovflw(a) ((opus_val32)(0-(opus_uint32)(a)))
+
 /** 16x16 multiplication where the result fits in 16 bits */
 #define MULT16_16_16(a,b)     ((((opus_val16)(a))*((opus_val16)(b))))
 
diff --git a/celt/float_cast.h b/celt/float_cast.h
index ed5a39b..98b40ab 100644
--- a/celt/float_cast.h
+++ b/celt/float_cast.h
@@ -61,7 +61,13 @@
 **      the config.h file.
 */
 
-#if (HAVE_LRINTF)
+/* With GCC, when SSE is available, the fastest conversion is cvtss2si. */
+#if defined(__GNUC__) && defined(__SSE__)
+
+#include <xmmintrin.h>
+static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));}
+
+#elif defined(HAVE_LRINTF)
 
 /*      These defines enable functionality introduced with the 1999 ISO C
 **      standard. They must be defined before the inclusion of math.h to
diff --git a/celt/kiss_fft.c b/celt/kiss_fft.c
index 1f8fd05..8377516 100644
--- a/celt/kiss_fft.c
+++ b/celt/kiss_fft.c
@@ -82,8 +82,8 @@
          C_SUB( Fout2[0] ,  Fout[0] , t );
          C_ADDTO( Fout[0] ,  t );
 
-         t.r = S_MUL(Fout2[1].r+Fout2[1].i, tw);
-         t.i = S_MUL(Fout2[1].i-Fout2[1].r, tw);
+         t.r = S_MUL(ADD32_ovflw(Fout2[1].r, Fout2[1].i), tw);
+         t.i = S_MUL(SUB32_ovflw(Fout2[1].i, Fout2[1].r), tw);
          C_SUB( Fout2[1] ,  Fout[1] , t );
          C_ADDTO( Fout[1] ,  t );
 
@@ -92,8 +92,8 @@
          C_SUB( Fout2[2] ,  Fout[2] , t );
          C_ADDTO( Fout[2] ,  t );
 
-         t.r = S_MUL(Fout2[3].i-Fout2[3].r, tw);
-         t.i = S_MUL(-Fout2[3].i-Fout2[3].r, tw);
+         t.r = S_MUL(SUB32_ovflw(Fout2[3].i, Fout2[3].r), tw);
+         t.i = S_MUL(NEG32_ovflw(ADD32_ovflw(Fout2[3].i, Fout2[3].r)), tw);
          C_SUB( Fout2[3] ,  Fout[3] , t );
          C_ADDTO( Fout[3] ,  t );
          Fout += 8;
@@ -126,10 +126,10 @@
          C_ADDTO( *Fout , scratch1 );
          C_SUB( scratch1 , Fout[1] , Fout[3] );
 
-         Fout[1].r = scratch0.r + scratch1.i;
-         Fout[1].i = scratch0.i - scratch1.r;
-         Fout[3].r = scratch0.r - scratch1.i;
-         Fout[3].i = scratch0.i + scratch1.r;
+         Fout[1].r = ADD32_ovflw(scratch0.r, scratch1.i);
+         Fout[1].i = SUB32_ovflw(scratch0.i, scratch1.r);
+         Fout[3].r = SUB32_ovflw(scratch0.r, scratch1.i);
+         Fout[3].i = ADD32_ovflw(scratch0.i, scratch1.r);
          Fout+=4;
       }
    } else {
@@ -160,10 +160,10 @@
             tw3 += fstride*3;
             C_ADDTO( *Fout , scratch[3] );
 
-            Fout[m].r = scratch[5].r + scratch[4].i;
-            Fout[m].i = scratch[5].i - scratch[4].r;
-            Fout[m3].r = scratch[5].r - scratch[4].i;
-            Fout[m3].i = scratch[5].i + scratch[4].r;
+            Fout[m].r = ADD32_ovflw(scratch[5].r, scratch[4].i);
+            Fout[m].i = SUB32_ovflw(scratch[5].i, scratch[4].r);
+            Fout[m3].r = SUB32_ovflw(scratch[5].r, scratch[4].i);
+            Fout[m3].i = ADD32_ovflw(scratch[5].i, scratch[4].r);
             ++Fout;
          }
       }
@@ -212,18 +212,18 @@
          tw1 += fstride;
          tw2 += fstride*2;
 
-         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
-         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+         Fout[m].r = SUB32_ovflw(Fout->r, HALF_OF(scratch[3].r));
+         Fout[m].i = SUB32_ovflw(Fout->i, HALF_OF(scratch[3].i));
 
          C_MULBYSCALAR( scratch[0] , epi3.i );
 
          C_ADDTO(*Fout,scratch[3]);
 
-         Fout[m2].r = Fout[m].r + scratch[0].i;
-         Fout[m2].i = Fout[m].i - scratch[0].r;
+         Fout[m2].r = ADD32_ovflw(Fout[m].r, scratch[0].i);
+         Fout[m2].i = SUB32_ovflw(Fout[m].i, scratch[0].r);
 
-         Fout[m].r -= scratch[0].i;
-         Fout[m].i += scratch[0].r;
+         Fout[m].r = SUB32_ovflw(Fout[m].r, scratch[0].i);
+         Fout[m].i = ADD32_ovflw(Fout[m].i, scratch[0].r);
 
          ++Fout;
       } while(--k);
@@ -282,22 +282,22 @@
          C_ADD( scratch[8],scratch[2],scratch[3]);
          C_SUB( scratch[9],scratch[2],scratch[3]);
 
-         Fout0->r += scratch[7].r + scratch[8].r;
-         Fout0->i += scratch[7].i + scratch[8].i;
+         Fout0->r = ADD32_ovflw(Fout0->r, ADD32_ovflw(scratch[7].r, scratch[8].r));
+         Fout0->i = ADD32_ovflw(Fout0->i, ADD32_ovflw(scratch[7].i, scratch[8].i));
 
-         scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
-         scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+         scratch[5].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,ya.r), S_MUL(scratch[8].r,yb.r)));
+         scratch[5].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,ya.r), S_MUL(scratch[8].i,yb.r)));
 
-         scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
-         scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+         scratch[6].r =  ADD32_ovflw(S_MUL(scratch[10].i,ya.i), S_MUL(scratch[9].i,yb.i));
+         scratch[6].i = NEG32_ovflw(ADD32_ovflw(S_MUL(scratch[10].r,ya.i), S_MUL(scratch[9].r,yb.i)));
 
          C_SUB(*Fout1,scratch[5],scratch[6]);
          C_ADD(*Fout4,scratch[5],scratch[6]);
 
-         scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
-         scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
-         scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
-         scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+         scratch[11].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,yb.r), S_MUL(scratch[8].r,ya.r)));
+         scratch[11].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,yb.r), S_MUL(scratch[8].i,ya.r)));
+         scratch[12].r = SUB32_ovflw(S_MUL(scratch[9].i,ya.i), S_MUL(scratch[10].i,yb.i));
+         scratch[12].i = SUB32_ovflw(S_MUL(scratch[10].r,yb.i), S_MUL(scratch[9].r,ya.i));
 
          C_ADD(*Fout2,scratch[11],scratch[12]);
          C_SUB(*Fout3,scratch[11],scratch[12]);
diff --git a/celt/mathops.h b/celt/mathops.h
index a0525a9..1f8a20c 100644
--- a/celt/mathops.h
+++ b/celt/mathops.h
@@ -38,11 +38,44 @@
 #include "entcode.h"
 #include "os_support.h"
 
+#define PI 3.141592653f
+
 /* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
 #define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)
 
 unsigned isqrt32(opus_uint32 _val);
 
+/* CELT doesn't need it for fixed-point, by analysis.c does. */
+#if !defined(FIXED_POINT) || defined(ANALYSIS_C)
+#define cA 0.43157974f
+#define cB 0.67848403f
+#define cC 0.08595542f
+#define cE ((float)PI/2)
+static OPUS_INLINE float fast_atan2f(float y, float x) {
+   float x2, y2;
+   x2 = x*x;
+   y2 = y*y;
+   /* For very small values, we don't care about the answer, so
+      we can just return 0. */
+   if (x2 + y2 < 1e-18f)
+   {
+      return 0;
+   }
+   if(x2<y2){
+      float den = (y2 + cB*x2) * (y2 + cC*x2);
+      return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
+   }else{
+      float den = (x2 + cB*y2) * (x2 + cC*y2);
+      return  x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
+   }
+}
+#undef cA
+#undef cB
+#undef cC
+#undef cD
+#endif
+
+
 #ifndef OVERRIDE_CELT_MAXABS16
 static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)
 {
@@ -80,7 +113,6 @@
 
 #ifndef FIXED_POINT
 
-#define PI 3.141592653f
 #define celt_sqrt(x) ((float)sqrt(x))
 #define celt_rsqrt(x) (1.f/celt_sqrt(x))
 #define celt_rsqrt_norm(x) (celt_rsqrt(x))
diff --git a/celt/mdct.c b/celt/mdct.c
index 5315ad1..5c6dab5 100644
--- a/celt/mdct.c
+++ b/celt/mdct.c
@@ -270,8 +270,8 @@
          int rev;
          kiss_fft_scalar yr, yi;
          rev = *bitrev++;
-         yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);
-         yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);
+         yr = ADD32_ovflw(S_MUL(*xp2, t[i]), S_MUL(*xp1, t[N4+i]));
+         yi = SUB32_ovflw(S_MUL(*xp1, t[i]), S_MUL(*xp2, t[N4+i]));
          /* We swap real and imag because we use an FFT instead of an IFFT. */
          yp[2*rev+1] = yr;
          yp[2*rev] = yi;
@@ -301,8 +301,8 @@
          t0 = t[i];
          t1 = t[N4+i];
          /* We'd scale up by 2 here, but instead it's done when mixing the windows */
-         yr = S_MUL(re,t0) + S_MUL(im,t1);
-         yi = S_MUL(re,t1) - S_MUL(im,t0);
+         yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
+         yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
          /* We swap real and imag because we're using an FFT instead of an IFFT. */
          re = yp1[1];
          im = yp1[0];
@@ -312,8 +312,8 @@
          t0 = t[(N4-i-1)];
          t1 = t[(N2-i-1)];
          /* We'd scale up by 2 here, but instead it's done when mixing the windows */
-         yr = S_MUL(re,t0) + S_MUL(im,t1);
-         yi = S_MUL(re,t1) - S_MUL(im,t0);
+         yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
+         yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
          yp1[0] = yr;
          yp0[1] = yi;
          yp0 += 2;
@@ -333,8 +333,8 @@
          kiss_fft_scalar x1, x2;
          x1 = *xp1;
          x2 = *yp1;
-         *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
-         *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
+         *yp1++ = SUB32_ovflw(MULT16_32_Q15(*wp2, x2), MULT16_32_Q15(*wp1, x1));
+         *xp1-- = ADD32_ovflw(MULT16_32_Q15(*wp1, x2), MULT16_32_Q15(*wp2, x1));
          wp1++;
          wp2--;
       }
diff --git a/celt/mips/vq_mipsr1.h b/celt/mips/vq_mipsr1.h
index 54cef86..fd18eab 100644
--- a/celt/mips/vq_mipsr1.h
+++ b/celt/mips/vq_mipsr1.h
@@ -36,9 +36,6 @@
 #include "mathops.h"
 #include "arch.h"
 
-static unsigned extract_collapse_mask(int *iy, int N, int B);
-static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X, int N, opus_val32 Ryy, opus_val16 gain);
-static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
 static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);
 
 #define OVERRIDE_vq_exp_rotation1
diff --git a/celt/modes.c b/celt/modes.c
index 911686e..390c5e8 100644
--- a/celt/modes.c
+++ b/celt/modes.c
@@ -427,7 +427,7 @@
    }
 #endif /* CUSTOM_MODES_ONLY */
    opus_free((opus_int16*)mode->eBands);
-   opus_free((opus_int16*)mode->allocVectors);
+   opus_free((unsigned char*)mode->allocVectors);
 
    opus_free((opus_val16*)mode->window);
    opus_free((opus_int16*)mode->logN);
diff --git a/celt/pitch.c b/celt/pitch.c
index bf46e7d..5b061d8 100644
--- a/celt/pitch.c
+++ b/celt/pitch.c
@@ -220,13 +220,8 @@
 #else
 void
 #endif
-#if defined(OVERRIDE_PITCH_XCORR)
 celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
-      opus_val32 *xcorr, int len, int max_pitch)
-#else
-celt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,
       opus_val32 *xcorr, int len, int max_pitch, int arch)
-#endif
 {
 
 #if 0 /* This is a simple version of the pitch correlation that should work
@@ -265,11 +260,7 @@
    for (i=0;i<max_pitch-3;i+=4)
    {
       opus_val32 sum[4]={0,0,0,0};
-#if defined(OVERRIDE_PITCH_XCORR)
-      xcorr_kernel_c(_x, _y+i, sum, len);
-#else
       xcorr_kernel(_x, _y+i, sum, len, arch);
-#endif
       xcorr[i]=sum[0];
       xcorr[i+1]=sum[1];
       xcorr[i+2]=sum[2];
@@ -285,11 +276,7 @@
    for (;i<max_pitch;i++)
    {
       opus_val32 sum;
-#if defined(OVERRIDE_PITCH_XCORR)
-      sum = celt_inner_prod_c(_x, _y+i, len);
-#else
       sum = celt_inner_prod(_x, _y+i, len, arch);
-#endif
       xcorr[i] = sum;
 #ifdef FIXED_POINT
       maxcorr = MAX32(maxcorr, sum);
@@ -378,7 +365,7 @@
       for (j=0;j<len>>1;j++)
          sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift);
 #else
-      sum = celt_inner_prod_c(x_lp, y+i, len>>1);
+      sum = celt_inner_prod(x_lp, y+i, len>>1, arch);
 #endif
       xcorr[i] = MAX32(-1, sum);
 #ifdef FIXED_POINT
@@ -424,7 +411,7 @@
    sx = celt_ilog2(xx)-14;
    sy = celt_ilog2(yy)-14;
    shift = sx + sy;
-   x2y2 = MULT16_16_Q14(VSHR32(xx, sx), VSHR32(yy, sy));
+   x2y2 = SHR32(MULT16_16(VSHR32(xx, sx), VSHR32(yy, sy)), 14);
    if (shift & 1) {
       if (x2y2 < 32768)
       {
diff --git a/celt/pitch.h b/celt/pitch.h
index d350353..e425f56 100644
--- a/celt/pitch.h
+++ b/celt/pitch.h
@@ -46,8 +46,7 @@
 #include "mips/pitch_mipsr1.h"
 #endif
 
-#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
-  || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
+#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
 # include "arm/pitch_arm.h"
 #endif
 
@@ -184,17 +183,10 @@
 void
 #endif
 celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
-      opus_val32 *xcorr, int len, int max_pitch);
-
-#if !defined(OVERRIDE_PITCH_XCORR)
-#ifdef FIXED_POINT
-opus_val32
-#else
-void
-#endif
-celt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,
       opus_val32 *xcorr, int len, int max_pitch, int arch);
 
+#ifndef OVERRIDE_PITCH_XCORR
+# define celt_pitch_xcorr celt_pitch_xcorr_c
 #endif
 
 #endif
diff --git a/celt/quant_bands.c b/celt/quant_bands.c
index 95076e0..56101b1 100644
--- a/celt/quant_bands.c
+++ b/celt/quant_bands.c
@@ -418,6 +418,7 @@
             offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
 #endif
             oldEBands[i+c*m->nbEBands] += offset;
+            error[i+c*m->nbEBands] -= offset;
             bits_left--;
          } while (++c < C);
       }
@@ -547,9 +548,15 @@
    c=0;
    do {
       for (i=0;i<effEnd;i++)
+      {
          bandLogE[i+c*m->nbEBands] =
-               celt_log2(SHL32(bandE[i+c*m->nbEBands],2))
+               celt_log2(bandE[i+c*m->nbEBands])
                - SHL16((opus_val16)eMeans[i],6);
+#ifdef FIXED_POINT
+         /* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */
+         bandLogE[i+c*m->nbEBands] += QCONST16(2.f, DB_SHIFT);
+#endif
+      }
       for (i=effEnd;i<end;i++)
          bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
    } while (++c < C);
diff --git a/celt/rate.c b/celt/rate.c
index 7dfa5be..ca4cc87 100644
--- a/celt/rate.c
+++ b/celt/rate.c
@@ -348,12 +348,17 @@
             /*This if() block is the only part of the allocation function that
                is not a mandatory part of the bitstream: any bands we choose to
                skip here must be explicitly signaled.*/
-            /*Choose a threshold with some hysteresis to keep bands from
-               fluctuating in and out.*/
+            int depth_threshold;
+            /*We choose a threshold with some hysteresis to keep bands from
+               fluctuating in and out, but we try not to fold below a certain point. */
+            if (codedBands > 17)
+               depth_threshold = j<prev ? 7 : 9;
+            else
+               depth_threshold = 0;
 #ifdef FUZZING
             if ((rand()&0x1) == 0)
 #else
-            if (codedBands<=start+2 || (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
+            if (codedBands<=start+2 || (band_bits > (depth_threshold*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
 #endif
             {
                ec_enc_bit_logp(ec, 1, 1);
diff --git a/celt/static_modes_fixed_arm_ne10.h b/celt/static_modes_fixed_arm_ne10.h
index b8ef0ce..7623092 100644
--- a/celt/static_modes_fixed_arm_ne10.h
+++ b/celt/static_modes_fixed_arm_ne10.h
@@ -1,7 +1,7 @@
 /* The contents of this file was automatically generated by
  * dump_mode_arm_ne10.c with arguments: 48000 960
  * It contains static definitions for some pre-defined modes. */
-#include <NE10_init.h>
+#include <NE10_types.h>
 
 #ifndef NE10_FFT_PARAMS48000_960
 #define NE10_FFT_PARAMS48000_960
diff --git a/celt/static_modes_float_arm_ne10.h b/celt/static_modes_float_arm_ne10.h
index 934a82a..66e1abb 100644
--- a/celt/static_modes_float_arm_ne10.h
+++ b/celt/static_modes_float_arm_ne10.h
@@ -1,7 +1,7 @@
 /* The contents of this file was automatically generated by
  * dump_mode_arm_ne10.c with arguments: 48000 960
  * It contains static definitions for some pre-defined modes. */
-#include <NE10_init.h>
+#include <NE10_types.h>
 
 #ifndef NE10_FFT_PARAMS48000_960
 #define NE10_FFT_PARAMS48000_960
diff --git a/celt/tests/test_unit_dft.c b/celt/tests/test_unit_dft.c
index 6166eb0..70f8f49 100644
--- a/celt/tests/test_unit_dft.c
+++ b/celt/tests/test_unit_dft.c
@@ -29,38 +29,12 @@
 #include "config.h"
 #endif
 
-#define SKIP_CONFIG_H
-
-#ifndef CUSTOM_MODES
-#define CUSTOM_MODES
-#endif
-
 #include <stdio.h>
 
-#define CELT_C
-#define TEST_UNIT_DFT_C
 #include "stack_alloc.h"
 #include "kiss_fft.h"
-#include "kiss_fft.c"
-#include "mathops.c"
-#include "entcode.c"
-
-#if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
-# include "x86/x86cpu.c"
-#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-# include "arm/armcpu.c"
-# include "celt_lpc.c"
-# include "pitch.c"
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-#  include "arm/celt_neon_intr.c"
-#  if defined(HAVE_ARM_NE10)
-#   include "mdct.c"
-#   include "arm/celt_ne10_fft.c"
-#   include "arm/celt_ne10_mdct.c"
-#  endif
-# endif
-# include "arm/arm_celt_map.c"
-#endif
+#include "mathops.h"
+#include "modes.h"
 
 #ifndef M_PI
 #define M_PI 3.141592653
@@ -112,11 +86,25 @@
 void test1d(int nfft,int isinverse,int arch)
 {
     size_t buflen = sizeof(kiss_fft_cpx)*nfft;
-
-    kiss_fft_cpx  * in = (kiss_fft_cpx*)malloc(buflen);
-    kiss_fft_cpx  * out= (kiss_fft_cpx*)malloc(buflen);
-    kiss_fft_state *cfg = opus_fft_alloc(nfft,0,0,arch);
+    kiss_fft_cpx *in;
+    kiss_fft_cpx *out;
     int k;
+#ifdef CUSTOM_MODES
+    kiss_fft_state *cfg = opus_fft_alloc(nfft,0,0,arch);
+#else
+    int id;
+    const kiss_fft_state *cfg;
+    CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
+    if (nfft == 480) id = 0;
+    else if (nfft == 240) id = 1;
+    else if (nfft == 120) id = 2;
+    else if (nfft == 60) id = 3;
+    else return;
+    cfg = mode->mdct.kfft[id];
+#endif
+
+    in = (kiss_fft_cpx*)malloc(buflen);
+    out = (kiss_fft_cpx*)malloc(buflen);
 
     for (k=0;k<nfft;++k) {
         in[k].r = (rand() % 32767) - 16384;
@@ -149,7 +137,9 @@
 
     free(in);
     free(out);
+#ifdef CUSTOM_MODES
     opus_fft_free(cfg, arch);
+#endif
 }
 
 int main(int argc,char ** argv)
diff --git a/celt/tests/test_unit_mathops.c b/celt/tests/test_unit_mathops.c
index fd3319d..874e9ad 100644
--- a/celt/tests/test_unit_mathops.c
+++ b/celt/tests/test_unit_mathops.c
@@ -34,48 +34,10 @@
 #define CUSTOM_MODES
 #endif
 
-#define CELT_C
-
 #include <stdio.h>
 #include <math.h>
-#include "mathops.c"
-#include "entenc.c"
-#include "entdec.c"
-#include "entcode.c"
-#include "bands.c"
-#include "quant_bands.c"
-#include "laplace.c"
-#include "vq.c"
-#include "cwrs.c"
-#include "pitch.c"
-#include "celt_lpc.c"
-#include "celt.c"
-
-#if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
-# if defined(OPUS_X86_MAY_HAVE_SSE)
-#  include "x86/pitch_sse.c"
-# endif
-# if defined(OPUS_X86_MAY_HAVE_SSE2)
-#  include "x86/pitch_sse2.c"
-# endif
-# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
-#  include "x86/pitch_sse4_1.c"
-#  include "x86/celt_lpc_sse.c"
-# endif
-# include "x86/x86_celt_map.c"
-#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-# include "arm/armcpu.c"
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-#  include "arm/celt_neon_intr.c"
-#  if defined(HAVE_ARM_NE10)
-#   include "kiss_fft.c"
-#   include "mdct.c"
-#   include "arm/celt_ne10_fft.c"
-#   include "arm/celt_ne10_mdct.c"
-#  endif
-# endif
-# include "arm/arm_celt_map.c"
-#endif
+#include "mathops.h"
+#include "bands.h"
 
 #ifdef FIXED_POINT
 #define WORD "%d"
diff --git a/celt/tests/test_unit_mdct.c b/celt/tests/test_unit_mdct.c
index 8dbb9ca..4a563cc 100644
--- a/celt/tests/test_unit_mdct.c
+++ b/celt/tests/test_unit_mdct.c
@@ -29,38 +29,13 @@
 #include "config.h"
 #endif
 
-#define SKIP_CONFIG_H
-
-#ifndef CUSTOM_MODES
-#define CUSTOM_MODES
-#endif
-
 #include <stdio.h>
 
-#define CELT_C
 #include "mdct.h"
 #include "stack_alloc.h"
-
-#include "kiss_fft.c"
-#include "mdct.c"
-#include "mathops.c"
-#include "entcode.c"
-
-#if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
-# include "x86/x86cpu.c"
-#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-# include "arm/armcpu.c"
-# include "pitch.c"
-# include "celt_lpc.c"
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-#  include "arm/celt_neon_intr.c"
-#  if defined(HAVE_ARM_NE10)
-#   include "arm/celt_ne10_fft.c"
-#   include "arm/celt_ne10_mdct.c"
-#  endif
-# endif
-# include "arm/arm_celt_map.c"
-#endif
+#include "kiss_fft.h"
+#include "mdct.h"
+#include "modes.h"
 
 #ifndef M_PI
 #define M_PI 3.141592653
@@ -130,16 +105,36 @@
 
 void test1d(int nfft,int isinverse,int arch)
 {
-    mdct_lookup cfg;
     size_t buflen = sizeof(kiss_fft_scalar)*nfft;
-
-    kiss_fft_scalar  * in = (kiss_fft_scalar*)malloc(buflen);
-    kiss_fft_scalar  * in_copy = (kiss_fft_scalar*)malloc(buflen);
-    kiss_fft_scalar  * out= (kiss_fft_scalar*)malloc(buflen);
-    opus_val16  * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
+    kiss_fft_scalar *in;
+    kiss_fft_scalar *in_copy;
+    kiss_fft_scalar *out;
+    opus_val16 *window;
     int k;
 
-    clt_mdct_init(&cfg, nfft, 0, arch);
+#ifdef CUSTOM_MODES
+    int shift = 0;
+    const mdct_lookup *cfg;
+    mdct_lookup _cfg;
+    clt_mdct_init(&_cfg, nfft, 0, arch);
+    cfg = &_cfg;
+#else
+    int shift;
+    const mdct_lookup *cfg;
+    CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
+    if (nfft == 1920) shift = 0;
+    else if (nfft == 960) shift = 1;
+    else if (nfft == 480) shift = 2;
+    else if (nfft == 240) shift = 3;
+    else return;
+    cfg = &mode->mdct;
+#endif
+
+    in = (kiss_fft_scalar*)malloc(buflen);
+    in_copy = (kiss_fft_scalar*)malloc(buflen);
+    out = (kiss_fft_scalar*)malloc(buflen);
+    window = (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
+
     for (k=0;k<nfft;++k) {
         in[k] = (rand() % 32768) - 16384;
     }
@@ -166,13 +161,13 @@
     {
        for (k=0;k<nfft;++k)
           out[k] = 0;
-       clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1, arch);
+       clt_mdct_backward(cfg,in,out, window, nfft/2, shift, 1, arch);
        /* apply TDAC because clt_mdct_backward() no longer does that */
        for (k=0;k<nfft/4;++k)
           out[nfft-k-1] = out[nfft/2+k];
        check_inv(in,out,nfft,isinverse);
     } else {
-       clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1, arch);
+       clt_mdct_forward(cfg,in,out,window, nfft/2, shift, 1, arch);
        check(in_copy,out,nfft,isinverse);
     }
     /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
@@ -182,7 +177,9 @@
     free(in_copy);
     free(out);
     free(window);
-    clt_mdct_clear(&cfg, arch);
+#ifdef CUSTOM_MODES
+    clt_mdct_clear(&_cfg, arch);
+#endif
 }
 
 int main(int argc,char ** argv)
diff --git a/celt/tests/test_unit_rotation.c b/celt/tests/test_unit_rotation.c
index 1080c20..267b983 100644
--- a/celt/tests/test_unit_rotation.c
+++ b/celt/tests/test_unit_rotation.c
@@ -37,43 +37,11 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "vq.c"
-#include "cwrs.c"
-#include "entcode.c"
-#include "entenc.c"
-#include "entdec.c"
-#include "mathops.c"
+#include "vq.h"
 #include "bands.h"
-#include "pitch.c"
-#include "celt_lpc.c"
-#include "celt.c"
+#include "stack_alloc.h"
 #include <math.h>
 
-#if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
-# if defined(OPUS_X86_MAY_HAVE_SSE)
-#  include "x86/pitch_sse.c"
-# endif
-# if defined(OPUS_X86_MAY_HAVE_SSE2)
-#  include "x86/pitch_sse2.c"
-# endif
-# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
-#  include "x86/pitch_sse4_1.c"
-#  include "x86/celt_lpc_sse.c"
-# endif
-# include "x86/x86_celt_map.c"
-#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-# include "arm/armcpu.c"
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-#  include "arm/celt_neon_intr.c"
-#  if defined(HAVE_ARM_NE10)
-#   include "kiss_fft.c"
-#   include "mdct.c"
-#   include "arm/celt_ne10_fft.c"
-#   include "arm/celt_ne10_mdct.c"
-#  endif
-# endif
-# include "arm/arm_celt_map.c"
-#endif
 
 #define MAX_SIZE 100
 
diff --git a/celt/vq.c b/celt/vq.c
index d29f38f..8ef80e5 100644
--- a/celt/vq.c
+++ b/celt/vq.c
@@ -67,7 +67,7 @@
 }
 #endif /* OVERRIDE_vq_exp_rotation1 */
 
-static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
+void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
 {
    static const int SPREAD_FACTOR[3]={15,10,5};
    int i;
@@ -158,42 +158,27 @@
    return collapse_mask;
 }
 
-unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
-#ifdef RESYNTH
-   , opus_val16 gain
-#endif
-   )
+opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
 {
    VARDECL(celt_norm, y);
-   VARDECL(int, iy);
-   VARDECL(opus_val16, signx);
+   VARDECL(int, signx);
    int i, j;
-   opus_val16 s;
    int pulsesLeft;
    opus_val32 sum;
    opus_val32 xy;
    opus_val16 yy;
-   unsigned collapse_mask;
    SAVE_STACK;
 
-   celt_assert2(K>0, "alg_quant() needs at least one pulse");
-   celt_assert2(N>1, "alg_quant() needs at least two dimensions");
-
+   (void)arch;
    ALLOC(y, N, celt_norm);
-   ALLOC(iy, N, int);
-   ALLOC(signx, N, opus_val16);
-
-   exp_rotation(X, N, 1, B, K, spread);
+   ALLOC(signx, N, int);
 
    /* Get rid of the sign */
    sum = 0;
    j=0; do {
-      if (X[j]>0)
-         signx[j]=1;
-      else {
-         signx[j]=-1;
-         X[j]=-X[j];
-      }
+      signx[j] = X[j]<0;
+      /* OPT: Make sure the compiler doesn't use a branch on ABS16(). */
+      X[j] = ABS16(X[j]);
       iy[j] = 0;
       y[j] = 0;
    } while (++j<N);
@@ -225,7 +210,12 @@
          while (++j<N);
          sum = QCONST16(1.f,14);
       }
-      rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum)));
+#ifdef FIXED_POINT
+      rcp = EXTRACT16(MULT16_32_Q16(K, celt_rcp(sum)));
+#else
+      /* Using K+e with e < 1 guarantees we cannot get more than K pulses. */
+      rcp = EXTRACT16(MULT16_32_Q16(K+0.8f, celt_rcp(sum)));
+#endif
       j=0; do {
 #ifdef FIXED_POINT
          /* It's really important to round *towards zero* here */
@@ -240,7 +230,7 @@
          pulsesLeft -= iy[j];
       }  while (++j<N);
    }
-   celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass");
+   celt_assert2(pulsesLeft>=0, "Allocated too many pulses in the quick pass");
 
    /* This should never happen, but just in case it does (e.g. on silence)
       we fill the first bin with pulses. */
@@ -256,12 +246,12 @@
       pulsesLeft=0;
    }
 
-   s = 1;
    for (i=0;i<pulsesLeft;i++)
    {
+      opus_val16 Rxy, Ryy;
       int best_id;
-      opus_val32 best_num = -VERY_LARGE16;
-      opus_val16 best_den = 0;
+      opus_val32 best_num;
+      opus_val16 best_den;
 #ifdef FIXED_POINT
       int rshift;
 #endif
@@ -272,9 +262,22 @@
       /* The squared magnitude term gets added anyway, so we might as well
          add it outside the loop */
       yy = ADD16(yy, 1);
-      j=0;
+
+      /* Calculations for position 0 are out of the loop, in part to reduce
+         mispredicted branches (since the if condition is usually false)
+         in the loop. */
+      /* Temporary sums of the new pulse(s) */
+      Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[0])),rshift));
+      /* We're multiplying y[j] by two so we don't have to do it here */
+      Ryy = ADD16(yy, y[0]);
+
+      /* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that
+         Rxy is positive because the sign is pre-computed) */
+      Rxy = MULT16_16_Q15(Rxy,Rxy);
+      best_den = Ryy;
+      best_num = Rxy;
+      j=1;
       do {
-         opus_val16 Rxy, Ryy;
          /* Temporary sums of the new pulse(s) */
          Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift));
          /* We're multiplying y[j] by two so we don't have to do it here */
@@ -285,8 +288,11 @@
          Rxy = MULT16_16_Q15(Rxy,Rxy);
          /* The idea is to check for num/den >= best_num/best_den, but that way
             we can do it without any division */
-         /* OPT: Make sure to use conditional moves here */
-         if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num))
+         /* OPT: It's not clear whether a cmov is faster than a branch here
+            since the condition is more often false than true and using
+            a cmov introduces data dependencies across iterations. The optimal
+            choice may be architecture-dependent. */
+         if (opus_unlikely(MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)))
          {
             best_den = Ryy;
             best_num = Rxy;
@@ -301,23 +307,47 @@
 
       /* Only now that we've made the final choice, update y/iy */
       /* Multiplying y[j] by 2 so we don't have to do it everywhere else */
-      y[best_id] += 2*s;
+      y[best_id] += 2;
       iy[best_id]++;
    }
 
    /* Put the original sign back */
    j=0;
    do {
-      X[j] = MULT16_16(signx[j],X[j]);
-      if (signx[j] < 0)
-         iy[j] = -iy[j];
+      /*iy[j] = signx[j] ? -iy[j] : iy[j];*/
+      /* OPT: The is more likely to be compiled without a branch than the code above
+         but has the same performance otherwise. */
+      iy[j] = (iy[j]^-signx[j]) + signx[j];
    } while (++j<N);
+   RESTORE_STACK;
+   return yy;
+}
+
+unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
+      opus_val16 gain, int resynth, int arch)
+{
+   VARDECL(int, iy);
+   opus_val16 yy;
+   unsigned collapse_mask;
+   SAVE_STACK;
+
+   celt_assert2(K>0, "alg_quant() needs at least one pulse");
+   celt_assert2(N>1, "alg_quant() needs at least two dimensions");
+
+   /* Covers vectorization by up to 4. */
+   ALLOC(iy, N+3, int);
+
+   exp_rotation(X, N, 1, B, K, spread);
+
+   yy = op_pvq_search(X, iy, K, N, arch);
+
    encode_pulses(iy, N, K, enc);
 
-#ifdef RESYNTH
-   normalise_residual(iy, X, N, yy, gain);
-   exp_rotation(X, N, -1, B, K, spread);
-#endif
+   if (resynth)
+   {
+      normalise_residual(iy, X, N, yy, gain);
+      exp_rotation(X, N, -1, B, K, spread);
+   }
 
    collapse_mask = extract_collapse_mask(iy, N, B);
    RESTORE_STACK;
@@ -401,7 +431,7 @@
    /* 0.63662 = 2/pi */
    itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
 #else
-   itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));
+   itheta = (int)floor(.5f+16384*0.63662f*fast_atan2f(side,mid));
 #endif
 
    return itheta;
diff --git a/celt/vq.h b/celt/vq.h
index 5cfcbe5..0dfe6af 100644
--- a/celt/vq.h
+++ b/celt/vq.h
@@ -37,10 +37,22 @@
 #include "entdec.h"
 #include "modes.h"
 
+#if (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT))
+#include "x86/vq_sse.h"
+#endif
+
 #if defined(MIPSr1_ASM)
 #include "mips/vq_mipsr1.h"
 #endif
 
+void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
+
+opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch);
+
+#if !defined(OVERRIDE_OP_PVQ_SEARCH)
+#define op_pvq_search(x, iy, K, N, arch) \
+    (op_pvq_search_c(x, iy, K, N, arch))
+#endif
 
 /** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
   * the pitch and a combination of pulses such that its norm is still equal
@@ -51,12 +63,8 @@
  * @param enc Entropy encoder state
  * @ret A mask indicating which blocks in the band received pulses
 */
-unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,
-      ec_enc *enc
-#ifdef RESYNTH
-      , opus_val16 gain
-#endif
-      );
+unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
+      opus_val16 gain, int resynth, int arch);
 
 /** Algebraic pulse decoder
  * @param X Decoded normalised spectrum (returned)
diff --git a/celt/x86/celt_lpc_sse.c b/celt/x86/celt_lpc_sse.c
index 67e5592..5478568 100644
--- a/celt/x86/celt_lpc_sse.c
+++ b/celt/x86/celt_lpc_sse.c
@@ -40,65 +40,23 @@
 
 #if defined(FIXED_POINT)
 
-void celt_fir_sse4_1(const opus_val16 *_x,
+void celt_fir_sse4_1(const opus_val16 *x,
          const opus_val16 *num,
-         opus_val16 *_y,
+         opus_val16 *y,
          int N,
          int ord,
-         opus_val16 *mem,
          int arch)
 {
     int i,j;
     VARDECL(opus_val16, rnum);
-    VARDECL(opus_val16, x);
 
     __m128i vecNoA;
     opus_int32 noA ;
     SAVE_STACK;
 
    ALLOC(rnum, ord, opus_val16);
-   ALLOC(x, N+ord, opus_val16);
    for(i=0;i<ord;i++)
       rnum[i] = num[ord-i-1];
-   for(i=0;i<ord;i++)
-      x[i] = mem[ord-i-1];
-
-   for (i=0;i<N-7;i+=8)
-   {
-       x[i+ord  ]=_x[i  ];
-       x[i+ord+1]=_x[i+1];
-       x[i+ord+2]=_x[i+2];
-       x[i+ord+3]=_x[i+3];
-       x[i+ord+4]=_x[i+4];
-       x[i+ord+5]=_x[i+5];
-       x[i+ord+6]=_x[i+6];
-       x[i+ord+7]=_x[i+7];
-   }
-
-   for (;i<N-3;i+=4)
-   {
-       x[i+ord  ]=_x[i  ];
-       x[i+ord+1]=_x[i+1];
-       x[i+ord+2]=_x[i+2];
-       x[i+ord+3]=_x[i+3];
-   }
-
-   for (;i<N;i++)
-         x[i+ord]=_x[i];
-
-   for(i=0;i<ord;i++)
-      mem[i] = _x[N-i-1];
-#ifdef SMALL_FOOTPRINT
-   for (i=0;i<N;i++)
-   {
-      opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
-      for (j=0;j<ord;j++)
-      {
-         sum = MAC16_16(sum,rnum[j],x[i+j]);
-      }
-      _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
-   }
-#else
    noA = EXTEND32(1) << SIG_SHIFT >> 1;
    vecNoA = _mm_set_epi32(noA, noA, noA, noA);
 
@@ -107,25 +65,24 @@
       opus_val32 sums[4] = {0};
       __m128i vecSum, vecX;
 
-      xcorr_kernel(rnum, x+i, sums, ord, arch);
+      xcorr_kernel(rnum, x+i-ord, sums, ord, arch);
 
       vecSum = _mm_loadu_si128((__m128i *)sums);
       vecSum = _mm_add_epi32(vecSum, vecNoA);
       vecSum = _mm_srai_epi32(vecSum, SIG_SHIFT);
-      vecX = OP_CVTEPI16_EPI32_M64(_x + i);
+      vecX = OP_CVTEPI16_EPI32_M64(x + i);
       vecSum = _mm_add_epi32(vecSum, vecX);
       vecSum = _mm_packs_epi32(vecSum, vecSum);
-      _mm_storel_epi64((__m128i *)(_y + i), vecSum);
+      _mm_storel_epi64((__m128i *)(y + i), vecSum);
    }
    for (;i<N;i++)
    {
       opus_val32 sum = 0;
       for (j=0;j<ord;j++)
-         sum = MAC16_16(sum, rnum[j], x[i + j]);
-      _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
+         sum = MAC16_16(sum, rnum[j], x[i+j-ord]);
+      y[i] = SATURATE16(ADD32(EXTEND32(x[i]), PSHR32(sum, SIG_SHIFT)));
    }
 
-#endif
    RESTORE_STACK;
 }
 
diff --git a/celt/x86/celt_lpc_sse.h b/celt/x86/celt_lpc_sse.h
index c5ec796..7d1ecf7 100644
--- a/celt/x86/celt_lpc_sse.h
+++ b/celt/x86/celt_lpc_sse.h
@@ -41,12 +41,11 @@
          opus_val16 *y,
          int N,
          int ord,
-         opus_val16 *mem,
          int arch);
 
 #if defined(OPUS_X86_PRESUME_SSE4_1)
-#define celt_fir(x, num, y, N, ord, mem, arch) \
-    ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, mem, arch))
+#define celt_fir(x, num, y, N, ord, arch) \
+    ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, arch))
 
 #else
 
@@ -56,11 +55,10 @@
          opus_val16 *y,
          int N,
          int ord,
-         opus_val16 *mem,
          int arch);
 
-#  define celt_fir(x, num, y, N, ord, mem, arch) \
-    ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, mem, arch))
+#  define celt_fir(x, num, y, N, ord, arch) \
+    ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, arch))
 
 #endif
 #endif
diff --git a/celt/x86/vq_sse.h b/celt/x86/vq_sse.h
new file mode 100644
index 0000000..b4efe8f
--- /dev/null
+++ b/celt/x86/vq_sse.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 2016  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.
+*/
+
+#ifndef VQ_SSE_H
+#define VQ_SSE_H
+
+#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT)
+#define OVERRIDE_OP_PVQ_SEARCH
+
+opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch);
+
+#if defined(OPUS_X86_PRESUME_SSE2)
+#define op_pvq_search(x, iy, K, N, arch) \
+    (op_pvq_search_sse2(x, iy, K, N, arch))
+
+#else
+
+extern opus_val16 (*const OP_PVQ_SEARCH_IMPL[OPUS_ARCHMASK + 1])(
+      celt_norm *_X, int *iy, int K, int N, int arch);
+
+#  define op_pvq_search(X, iy, K, N, arch) \
+    ((*OP_PVQ_SEARCH_IMPL[(arch) & OPUS_ARCHMASK])(X, iy, K, N, arch))
+
+#endif
+#endif
+
+#endif
diff --git a/celt/x86/vq_sse2.c b/celt/x86/vq_sse2.c
new file mode 100644
index 0000000..6a31770
--- /dev/null
+++ b/celt/x86/vq_sse2.c
@@ -0,0 +1,217 @@
+/* Copyright (c) 2007-2008 CSIRO
+   Copyright (c) 2007-2009 Xiph.Org Foundation
+   Copyright (c) 2007-2016 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
+
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#include "celt_lpc.h"
+#include "stack_alloc.h"
+#include "mathops.h"
+#include "vq.h"
+#include "x86cpu.h"
+
+
+#ifndef FIXED_POINT
+
+opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch)
+{
+   int i, j;
+   int pulsesLeft;
+   float xy, yy;
+   VARDECL(celt_norm, y);
+   VARDECL(celt_norm, X);
+   VARDECL(float, signy);
+   __m128 signmask;
+   __m128 sums;
+   __m128i fours;
+   SAVE_STACK;
+
+   (void)arch;
+   /* All bits set to zero, except for the sign bit. */
+   signmask = _mm_set_ps1(-0.f);
+   fours = _mm_set_epi32(4, 4, 4, 4);
+   ALLOC(y, N+3, celt_norm);
+   ALLOC(X, N+3, celt_norm);
+   ALLOC(signy, N+3, float);
+
+   OPUS_COPY(X, _X, N);
+   X[N] = X[N+1] = X[N+2] = 0;
+   sums = _mm_setzero_ps();
+   for (j=0;j<N;j+=4)
+   {
+      __m128 x4, s4;
+      x4 = _mm_loadu_ps(&X[j]);
+      s4 = _mm_cmplt_ps(x4, _mm_setzero_ps());
+      /* Get rid of the sign */
+      x4 = _mm_andnot_ps(signmask, x4);
+      sums = _mm_add_ps(sums, x4);
+      /* Clear y and iy in case we don't do the projection. */
+      _mm_storeu_ps(&y[j], _mm_setzero_ps());
+      _mm_storeu_si128((__m128i*)&iy[j], _mm_setzero_si128());
+      _mm_storeu_ps(&X[j], x4);
+      _mm_storeu_ps(&signy[j], s4);
+   }
+   sums = _mm_add_ps(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(1, 0, 3, 2)));
+   sums = _mm_add_ps(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(2, 3, 0, 1)));
+
+   xy = yy = 0;
+
+   pulsesLeft = K;
+
+   /* Do a pre-search by projecting on the pyramid */
+   if (K > (N>>1))
+   {
+      __m128i pulses_sum;
+      __m128 yy4, xy4;
+      __m128 rcp4;
+      opus_val32 sum = _mm_cvtss_f32(sums);
+      /* If X is too small, just replace it with a pulse at 0 */
+      /* Prevents infinities and NaNs from causing too many pulses
+         to be allocated. 64 is an approximation of infinity here. */
+      if (!(sum > EPSILON && sum < 64))
+      {
+         X[0] = QCONST16(1.f,14);
+         j=1; do
+            X[j]=0;
+         while (++j<N);
+         sums = _mm_set_ps1(1.f);
+      }
+      /* Using K+e with e < 1 guarantees we cannot get more than K pulses. */
+      rcp4 = _mm_mul_ps(_mm_set_ps1((float)(K+.8)), _mm_rcp_ps(sums));
+      xy4 = yy4 = _mm_setzero_ps();
+      pulses_sum = _mm_setzero_si128();
+      for (j=0;j<N;j+=4)
+      {
+         __m128 rx4, x4, y4;
+         __m128i iy4;
+         x4 = _mm_loadu_ps(&X[j]);
+         rx4 = _mm_mul_ps(x4, rcp4);
+         iy4 = _mm_cvttps_epi32(rx4);
+         pulses_sum = _mm_add_epi32(pulses_sum, iy4);
+         _mm_storeu_si128((__m128i*)&iy[j], iy4);
+         y4 = _mm_cvtepi32_ps(iy4);
+         xy4 = _mm_add_ps(xy4, _mm_mul_ps(x4, y4));
+         yy4 = _mm_add_ps(yy4, _mm_mul_ps(y4, y4));
+         /* double the y[] vector so we don't have to do it in the search loop. */
+         _mm_storeu_ps(&y[j], _mm_add_ps(y4, y4));
+      }
+      pulses_sum = _mm_add_epi32(pulses_sum, _mm_shuffle_epi32(pulses_sum, _MM_SHUFFLE(1, 0, 3, 2)));
+      pulses_sum = _mm_add_epi32(pulses_sum, _mm_shuffle_epi32(pulses_sum, _MM_SHUFFLE(2, 3, 0, 1)));
+      pulsesLeft -= _mm_cvtsi128_si32(pulses_sum);
+      xy4 = _mm_add_ps(xy4, _mm_shuffle_ps(xy4, xy4, _MM_SHUFFLE(1, 0, 3, 2)));
+      xy4 = _mm_add_ps(xy4, _mm_shuffle_ps(xy4, xy4, _MM_SHUFFLE(2, 3, 0, 1)));
+      xy = _mm_cvtss_f32(xy4);
+      yy4 = _mm_add_ps(yy4, _mm_shuffle_ps(yy4, yy4, _MM_SHUFFLE(1, 0, 3, 2)));
+      yy4 = _mm_add_ps(yy4, _mm_shuffle_ps(yy4, yy4, _MM_SHUFFLE(2, 3, 0, 1)));
+      yy = _mm_cvtss_f32(yy4);
+   }
+   X[N] = X[N+1] = X[N+2] = -100;
+   y[N] = y[N+1] = y[N+2] = 100;
+   celt_assert2(pulsesLeft>=0, "Allocated too many pulses in the quick pass");
+
+   /* This should never happen, but just in case it does (e.g. on silence)
+      we fill the first bin with pulses. */
+   if (pulsesLeft > N+3)
+   {
+      opus_val16 tmp = (opus_val16)pulsesLeft;
+      yy = MAC16_16(yy, tmp, tmp);
+      yy = MAC16_16(yy, tmp, y[0]);
+      iy[0] += pulsesLeft;
+      pulsesLeft=0;
+   }
+
+   for (i=0;i<pulsesLeft;i++)
+   {
+      int best_id;
+      __m128 xy4, yy4;
+      __m128 max, max2;
+      __m128i count;
+      __m128i pos;
+      /* The squared magnitude term gets added anyway, so we might as well
+         add it outside the loop */
+      yy = ADD16(yy, 1);
+      xy4 = _mm_load1_ps(&xy);
+      yy4 = _mm_load1_ps(&yy);
+      max = _mm_setzero_ps();
+      pos = _mm_setzero_si128();
+      count = _mm_set_epi32(3, 2, 1, 0);
+      for (j=0;j<N;j+=4)
+      {
+         __m128 x4, y4, r4;
+         x4 = _mm_loadu_ps(&X[j]);
+         y4 = _mm_loadu_ps(&y[j]);
+         x4 = _mm_add_ps(x4, xy4);
+         y4 = _mm_add_ps(y4, yy4);
+         y4 = _mm_rsqrt_ps(y4);
+         r4 = _mm_mul_ps(x4, y4);
+         /* Update the index of the max. */
+         pos = _mm_max_epi16(pos, _mm_and_si128(count, _mm_castps_si128(_mm_cmpgt_ps(r4, max))));
+         /* Update the max. */
+         max = _mm_max_ps(max, r4);
+         /* Update the indices (+4) */
+         count = _mm_add_epi32(count, fours);
+      }
+      /* Horizontal max */
+      max2 = _mm_max_ps(max, _mm_shuffle_ps(max, max, _MM_SHUFFLE(1, 0, 3, 2)));
+      max2 = _mm_max_ps(max2, _mm_shuffle_ps(max2, max2, _MM_SHUFFLE(2, 3, 0, 1)));
+      /* Now that max2 contains the max at all positions, look at which value(s) of the
+         partial max is equal to the global max. */
+      pos = _mm_and_si128(pos, _mm_castps_si128(_mm_cmpeq_ps(max, max2)));
+      pos = _mm_max_epi16(pos, _mm_unpackhi_epi64(pos, pos));
+      pos = _mm_max_epi16(pos, _mm_shufflelo_epi16(pos, _MM_SHUFFLE(1, 0, 3, 2)));
+      best_id = _mm_cvtsi128_si32(pos);
+
+      /* Updating the sums of the new pulse(s) */
+      xy = ADD32(xy, EXTEND32(X[best_id]));
+      /* We're multiplying y[j] by two so we don't have to do it here */
+      yy = ADD16(yy, y[best_id]);
+
+      /* Only now that we've made the final choice, update y/iy */
+      /* Multiplying y[j] by 2 so we don't have to do it everywhere else */
+      y[best_id] += 2;
+      iy[best_id]++;
+   }
+
+   /* Put the original sign back */
+   for (j=0;j<N;j+=4)
+   {
+      __m128i y4;
+      __m128i s4;
+      y4 = _mm_loadu_si128((__m128i*)&iy[j]);
+      s4 = _mm_castps_si128(_mm_loadu_ps(&signy[j]));
+      y4 = _mm_xor_si128(_mm_add_epi32(y4, s4), s4);
+      _mm_storeu_si128((__m128i*)&iy[j], y4);
+   }
+   RESTORE_STACK;
+   return yy;
+}
+
+#endif
diff --git a/celt/x86/x86_celt_map.c b/celt/x86/x86_celt_map.c
index 47ba41b..d39d88e 100644
--- a/celt/x86/x86_celt_map.c
+++ b/celt/x86/x86_celt_map.c
@@ -33,6 +33,7 @@
 #include "celt_lpc.h"
 #include "pitch.h"
 #include "pitch_sse.h"
+#include "vq.h"
 
 #if defined(OPUS_HAVE_RTCD)
 
@@ -46,7 +47,6 @@
          opus_val16       *y,
          int              N,
          int              ord,
-         opus_val16       *mem,
          int              arch
 ) = {
   celt_fir_c,                /* non-sse */
@@ -151,5 +151,17 @@
 
 #endif
 
+#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)
+opus_val16 (*const OP_PVQ_SEARCH_IMPL[OPUS_ARCHMASK + 1])(
+      celt_norm *_X, int *iy, int K, int N, int arch
+) = {
+  op_pvq_search_c,                /* non-sse */
+  op_pvq_search_c,
+  MAY_HAVE_SSE2(op_pvq_search),
+  MAY_HAVE_SSE2(op_pvq_search),
+  MAY_HAVE_SSE2(op_pvq_search)
+};
+#endif
+
 #endif
 #endif
diff --git a/celt_headers.mk b/celt_headers.mk
index c9df94b..706185d 100644
--- a/celt_headers.mk
+++ b/celt_headers.mk
@@ -49,4 +49,5 @@
 celt/mips/pitch_mipsr1.h \
 celt/mips/vq_mipsr1.h \
 celt/x86/pitch_sse.h \
+celt/x86/vq_sse.h \
 celt/x86/x86cpu.h
diff --git a/celt_sources.mk b/celt_sources.mk
index 2ffe99a..f7d81cc 100644
--- a/celt_sources.mk
+++ b/celt_sources.mk
@@ -17,13 +17,17 @@
 celt/rate.c \
 celt/vq.c
 
-CELT_SOURCES_SSE = celt/x86/x86cpu.c \
+CELT_SOURCES_SSE = \
+celt/x86/x86cpu.c \
 celt/x86/x86_celt_map.c \
 celt/x86/pitch_sse.c
 
-CELT_SOURCES_SSE2 = celt/x86/pitch_sse2.c
+CELT_SOURCES_SSE2 = \
+celt/x86/pitch_sse2.c \
+celt/x86/vq_sse2.c
 
-CELT_SOURCES_SSE4_1 = celt/x86/celt_lpc_sse.c \
+CELT_SOURCES_SSE4_1 = \
+celt/x86/celt_lpc_sse.c \
 celt/x86/pitch_sse4_1.c
 
 CELT_SOURCES_ARM = \
@@ -37,8 +41,9 @@
 celt/arm/armopts.s.in
 
 CELT_SOURCES_ARM_NEON_INTR = \
-celt/arm/celt_neon_intr.c
+celt/arm/celt_neon_intr.c \
+celt/arm/pitch_neon_intr.c
 
-CELT_SOURCES_ARM_NE10= \
+CELT_SOURCES_ARM_NE10 = \
 celt/arm/celt_ne10_fft.c \
 celt/arm/celt_ne10_mdct.c
diff --git a/configure.ac b/configure.ac
index 7d3279d..5ffa2d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,9 +22,9 @@
 
 # For libtool.
 dnl Please update these for releases.
-OPUS_LT_CURRENT=5
-OPUS_LT_REVISION=4
-OPUS_LT_AGE=5
+OPUS_LT_CURRENT=6
+OPUS_LT_REVISION=1
+OPUS_LT_AGE=6
 
 AC_SUBST(OPUS_LT_CURRENT)
 AC_SUBST(OPUS_LT_REVISION)
@@ -421,12 +421,12 @@
       fi
 
       AC_MSG_CHECKING(for NE10)
-      save_CFLAGS="$CFLAGS"; CFLAGS="$NE10_CFLAGS"
-      save_LIBS="$LIBS"; LIBS="$NE10_LIBS $LIBM"
+      save_CFLAGS="$CFLAGS"; CFLAGS="$CFLAGS $NE10_CFLAGS"
+      save_LIBS="$LIBS"; LIBS="$LIBS $NE10_LIBS $LIBM"
       AC_LINK_IFELSE(
          [
             AC_LANG_PROGRAM(
-               [[#include <NE10_init.h>
+               [[#include <NE10_dsp.h>
                ]],
                [[
                   ne10_fft_cfg_float32_t cfg;
@@ -715,7 +715,7 @@
             ]])],
             [AC_MSG_RESULT([C method])
                  AC_DEFINE([CPU_INFO_BY_C], [1], [Get CPU Info by c method])],
-            [AC_MSG_ERROR([no supported Get CPU Info method, please disable intrinsics])])])])
+            [AC_MSG_ERROR([no supported Get CPU Info method, please disable run-time CPU capabilities detection or intrinsics])])])])
    ],
    [
       AC_MSG_WARN([No intrinsics support for your architecture])
@@ -767,6 +767,15 @@
   AC_DEFINE([FUZZING], [1], [Fuzzing])
 ])
 
+AC_ARG_ENABLE([check-asm],
+    [AS_HELP_STRING([--enable-check-asm],
+                    [enable bit-exactness checks between optimized and c implementations])],,
+    [enable_check_asm=no])
+
+AS_IF([test "$enable_check_asm" = "yes"], [
+  AC_DEFINE([OPUS_CHECK_ASM], [1], [Run bit-exactness checks between optimized and c implementations])
+])
+
 AC_ARG_ENABLE([ambisonics],
     [AS_HELP_STRING([--enable-ambisonics],[enable experimental ambisonic encoding and decoding support])],,
     [enable_ambisonics=no])
@@ -781,6 +790,7 @@
 
 AS_IF([test "$enable_doc" = "yes"], [
   AC_CHECK_PROG(HAVE_DOXYGEN, [doxygen], [yes], [no])
+  AC_CHECK_PROG(HAVE_DOT, [dot], [yes], [no])
 ],[
   HAVE_DOXYGEN=no
 ])
@@ -794,6 +804,15 @@
 AM_CONDITIONAL([EXTRA_PROGRAMS], [test "$enable_extra_programs" = "yes"])
 
 
+AC_ARG_ENABLE([update-draft],
+  AS_HELP_STRING([--enable-update-draft], [Enable bitstream changes from draft-ietf-codec-opus-update]),,
+  [enable_update_draft=no])
+
+AS_IF([test "$enable_update_draft" = "yes"], [
+  AC_DEFINE([ENABLE_UPDATE_DRAFT], [1], [Enable bitstream changes from draft-ietf-codec-opus-update])
+])
+
+
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -fvisibility=hidden"
 AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
@@ -859,7 +878,8 @@
       Custom modes: .................. ${enable_custom_modes}
       Assertion checking: ............ ${enable_assertions}
       Fuzzing: ....................... ${enable_fuzzing}
-      Ambisonics support: .............${enable_ambisonics}
+      Check ASM: ..................... ${enable_check_asm}
+      Ambisonics support: ............ ${enable_ambisonics}
 
       API documentation: ............. ${enable_doc}
       Extra programs: ................ ${enable_extra_programs}
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index cd77675..36eee0b 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -318,3 +318,18 @@
                          OPUS_CUSTOM_EXPORT_STATIC= \
                          OPUS_WARN_UNUSED_RESULT= \
                          OPUS_ARG_NONNULL(_x)=
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs.
+
+# Debian defaults to YES here, while Fedora and Homebrew default to NO.
+# So we set this based on whether the graphviz package is available at
+# configure time.
+#
+HAVE_DOT = @HAVE_DOT@
diff --git a/doc/draft-ietf-codec-opus-update.xml b/doc/draft-ietf-codec-opus-update.xml
index 8522857..a97124f 100644
--- a/doc/draft-ietf-codec-opus-update.xml
+++ b/doc/draft-ietf-codec-opus-update.xml
@@ -10,7 +10,7 @@
 <?rfc inline="yes"?>
 <?rfc compact="yes"?>
 <?rfc subcompact="no"?>
-<rfc category="std" docName="draft-ietf-codec-opus-update-02"
+<rfc category="std" docName="draft-ietf-codec-opus-update-06"
      ipr="trust200902">
   <front>
     <title abbrev="Opus Update">Updates to the Opus Audio Codec</title>
@@ -47,7 +47,7 @@
 
 
 
-    <date day="1" month="July" year="2016" />
+    <date day="19" month="June" year="2017" />
 
     <abstract>
       <t>This document addresses minor issues that were found in the specification
@@ -61,10 +61,24 @@
       implementation of the Opus codec that serves as the specification in
       <xref target="RFC6716">RFC 6716</xref>. Only issues affecting the decoder are
       listed here. An up-to-date implementation of the Opus encoder can be found at
-      http://opus-codec.org/. The updated specification remains fully compatible with
-      the original specification and only one of the changes results in any difference
-      in the audio output.
-      </t>
+      https://opus-codec.org/.</t>
+    <t>
+      Some of the changes in this document update normative behaviour in a way that requires
+      new test vectors. The English text of the specification is unaffected, only
+      the C implementation is. The updated specification remains fully compatible with
+      the original specification.
+    </t>
+
+    <t>
+    Note: due to RFC formatting conventions, lines exceeding the column width
+    in the patch are split using a backslash character. The backslashes
+    at the end of a line and the white space at the beginning
+    of the following line are not part of the patch. A properly formatted patch
+    including all changes is available at
+    <eref target="https://jmvalin.ca/misc_stuff/opus_update.patch"/>. (EDITOR:
+        change to an ietf.org link when ready)
+    </t>
+
     </section>
 
     <section title="Terminology">
@@ -156,7 +170,7 @@
      the batch sizes are reasonable enough that none of the issues above
      was ever a problem. However, proving that is non-obvious.
     </t>
-    <t>The code can be fixed by applying the following changes to line 70 of silk/resampler_private_IIR_FIR.c:
+    <t>The code can be fixed by applying the following changes to line 78 of silk/resampler_private_IIR_FIR.c:
     </t>
 <figure>
 <artwork><![CDATA[
@@ -214,30 +228,78 @@
  }
 ]]></artwork>
 </figure>
-    <t>
-    Note: due to RFC formatting conventions, lines exceeding the column width
-    in the patch above are split using a backslash character. The backslashes
-    at the end of a line and the white space at the beginning
-    of the following line are not part of the patch. A properly formatted patch
-    including the three changes above is available at
-    <eref target="https://jmvalin.ca/misc_stuff/opus_update.patch"/>. (EDITOR:
-        change to an ietf.org link when ready)
-    </t>
     </section>
 
-    <section title="Downmix to Mono" anchor="stereo">
-      <t>The last issue is not strictly a bug, but it is an issue that has been reported
-      when downmixing an Opus decoded stream to mono, whether this is done inside the decoder
-      or as a post-processing step on the stereo decoder output. Opus intensity stereo allows
-      optionally coding the two channels 180-degrees out of phase on a per-band basis.
-      This provides better stereo quality than forcing the two channels to be in phase,
-      but when the output is downmixed to mono, the energy in the affected bands is cancelled
-      sometimes resulting in audible artefacts.
+    <section title="Integer wrap-around in inverse gain computation">
+      <t>
+        It was discovered through decoder fuzzing that some bitstreams could produce
+        integer values exceeding 32-bits in LPC_inverse_pred_gain_QA(), causing
+        a wrap-around. Although the error is harmless in practice, the C standard considers
+        the behavior as undefined, so the following patch to line 87 of silk/LPC_inv_pred_gain.c
+        detects values that do not fit in a 32-bit integer and considers the corresponding filters unstable:
       </t>
-      <t>As a work-around for this issue, the decoder MAY choose not to apply the 180-degree
-      phase shift when the output is meant to be downmixed (inside or
-      outside of the decoder).
+<figure>
+<artwork><![CDATA[
+         /* Update AR coefficient */
+         for( n = 0; n < k; n++ ) {
+-            tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( \
+Aold_QA[ k - n - 1 ], rc_Q31, 31 );
+-            Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
++            opus_int64 tmp64;
++            tmp_QA = silk_SUB_SAT32( Aold_QA[ n ], MUL32_FRAC_Q( \
+Aold_QA[ k - n - 1 ], rc_Q31, 31 ) );
++            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( tmp_QA, \
+rc_mult2 ), mult2Q);
++            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
++               return 0;
++            }
++            Anew_QA[ n ] = ( opus_int32 )tmp64;
+         }
+]]></artwork>
+</figure>
+    </section>
+
+    <section title="Integer wrap-around in LSF decoding">
+      <t>
+        It was discovered -- also from decoder fuzzing -- that an integer wrap-around could
+        occur when decoding line spectral frequency coefficients from extreme bitstreams.
+        The end result of the wrap-around is an illegal read access on the stack, which
+        the authors do not believe is exploitable but should nonetheless be fixed. The following
+        patch to line 137 of silk/NLSF_stabilize.c prevents the problem:
       </t>
+<figure>
+<artwork><![CDATA[
+           /* Keep delta_min distance between the NLSFs */
+         for( i = 1; i < L; i++ )
+-            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
+NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
++            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
+silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
+ 
+         /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
+]]></artwork>
+</figure>
+
+    </section>
+
+    <section title="Cap on Band Energy">
+      <t>On extreme bit-streams, it is possible for log-domain band energy levels
+        to exceed the maximum single-precision floating point value once converted
+        to a linear scale. This would later cause the decoded values to be NaN,
+        possibly causing problems in the software using the PCM values. This can be
+        avoided with the following patch to line 552 of celt/quant_bands.c:
+      </t>
+<figure>
+<artwork><![CDATA[
+       {
+          opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
+                          SHL16((opus_val16)eMeans[i],6));
++         lg = MIN32(QCONST32(32.f, 16), lg);
+          eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
+       }
+       for (;i<m->nbEBands;i++)
+]]></artwork>
+</figure>
     </section>
 
     <section title="Hybrid Folding" anchor="folding">
@@ -249,7 +311,7 @@
         can cause audible pre-echo.
       </t>
       <t>
-        To address the issue, we change the folding behaviour so that it is
+        To address the issue, we change the folding behavior so that it is
         never forced to fall back to LCG due to the first band not containing
         enough coefficients to fold onto the second band. This
         is achieved by simply repeating part of the first band in the folding
@@ -309,20 +371,35 @@
       <t>
         The fix does not impact compatibility, because the improvement does
         not depend on the encoder doing anything special. There is also no
-        reasonable way for an encoder to use the original behaviour to
+        reasonable way for an encoder to use the original behavior to
         improve quality over the proposed change.
       </t>
     </section>
 
+    <section title="Downmix to Mono" anchor="stereo">
+      <t>The last issue is not strictly a bug, but it is an issue that has been reported
+      when downmixing an Opus decoded stream to mono, whether this is done inside the decoder
+      or as a post-processing step on the stereo decoder output. Opus intensity stereo allows
+      optionally coding the two channels 180-degrees out of phase on a per-band basis.
+      This provides better stereo quality than forcing the two channels to be in phase,
+      but when the output is downmixed to mono, the energy in the affected bands is cancelled
+      sometimes resulting in audible artefacts.
+      </t>
+      <t>As a work-around for this issue, the decoder MAY choose not to apply the 180-degree
+      phase shift when the output is meant to be downmixed (inside or
+      outside of the decoder).
+      </t>
+    </section>
+
+
     <section title="New Test Vectors">
-      <t>Changes in <xref target="stereo"/> and <xref target="folding"/> have
+      <t>Changes in <xref target="folding"/> and <xref target="stereo"/> have
         sufficient impact on the testvectors to make them fail. For this reason,
         this document also updates the Opus test vectors. The new test vectors now
         include two decoded outputs for the same bitstream. The outputs with
         suffix 'm' do not apply the CELT 180-degree phase shift as allowed in
-        <xref target="stereo"/>, while the outputs with suffix 's' do. An
-        implementation is compliant as long as it passes either the 'm' or the
-        's' set of vectors.
+        <xref target="stereo"/>, while the outputs without the suffix do. An
+        implementation is compliant as long as it passes either set of vectors.
       </t>
       <t>
         In addition, any Opus implementation
@@ -345,7 +422,8 @@
 
     <section anchor="Acknowledgements" title="Acknowledgements">
       <t>We would like to thank Juri Aedla for reporting the issue with the parsing of
-      the Opus padding.</t>
+      the Opus padding. Also, thanks to Jonathan Lennox and Mark Harris for their
+      feedback on this document.</t>
     </section>
   </middle>
 
diff --git a/doc/opus_update.patch b/doc/opus_update.patch
new file mode 100644
index 0000000..11f066c
--- /dev/null
+++ b/doc/opus_update.patch
@@ -0,0 +1,244 @@
+diff --git a/celt/bands.c b/celt/bands.c
+index 6962587..32e1de6 100644
+--- a/celt/bands.c
++++ b/celt/bands.c
+@@ -1234,9 +1234,23 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
+          b = 0;
+       }
+ 
+-      if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
++      if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0))
+             lowband_offset = i;
+ 
++      if (i == start+1)
++      {
++         int n1, n2;
++         int offset;
++         n1 = M*(eBands[start+1]-eBands[start]);
++         n2 = M*(eBands[start+2]-eBands[start+1]);
++         offset = M*eBands[start];
++         /* Duplicate enough of the first band folding data to be able to fold the second band.
++            Copies no data for CELT-only mode. */
++         OPUS_COPY(&norm[offset+n1], &norm[offset+2*n1 - n2], n2-n1);
++         if (C==2)
++            OPUS_COPY(&norm2[offset+n1], &norm2[offset+2*n1 - n2], n2-n1);
++      }
++
+       tf_change = tf_res[i];
+       if (i>=m->effEBands)
+       {
+@@ -1257,7 +1271,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
+          fold_start = lowband_offset;
+          while(M*eBands[--fold_start] > effective_lowband);
+          fold_end = lowband_offset-1;
+-         while(M*eBands[++fold_end] < effective_lowband+N);
++         while(++fold_end < i && M*eBands[fold_end] < effective_lowband+N);
+          x_cm = y_cm = 0;
+          fold_i = fold_start; do {
+            x_cm |= collapse_masks[fold_i*C+0];
+diff --git a/celt/quant_bands.c b/celt/quant_bands.c
+index e5ed9ef..82fb823 100644
+--- a/celt/quant_bands.c
++++ b/celt/quant_bands.c
+@@ -552,6 +552,7 @@ void log2Amp(const CELTMode *m, int start, int end,
+       {
+          opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
+                          SHL16((opus_val16)eMeans[i],6));
++         lg = MIN32(QCONST32(32.f, 16), lg);
+          eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
+       }
+       for (;i<m->nbEBands;i++)
+diff --git a/silk/LPC_inv_pred_gain.c b/silk/LPC_inv_pred_gain.c
+index 60c439b..6c301da 100644
+--- a/silk/LPC_inv_pred_gain.c
++++ b/silk/LPC_inv_pred_gain.c
+@@ -84,8 +84,13 @@ static opus_int32 LPC_inverse_pred_gain_QA(                 /* O   Returns inver
+ 
+         /* Update AR coefficient */
+         for( n = 0; n < k; n++ ) {
+-            tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 );
+-            Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
++            opus_int64 tmp64;
++            tmp_QA = silk_SUB_SAT32( Aold_QA[ n ], MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ) );
++            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( tmp_QA, rc_mult2 ), mult2Q);
++            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
++               return 0;
++            }
++            Anew_QA[ n ] = ( opus_int32 )tmp64;
+         }
+     }
+ 
+diff --git a/silk/NLSF_stabilize.c b/silk/NLSF_stabilize.c
+index 979aaba..2ef2398 100644
+--- a/silk/NLSF_stabilize.c
++++ b/silk/NLSF_stabilize.c
+@@ -134,7 +134,7 @@ void silk_NLSF_stabilize(
+ 
+         /* Keep delta_min distance between the NLSFs */
+         for( i = 1; i < L; i++ )
+-            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
++            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
+ 
+         /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
+         NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
+diff --git a/silk/dec_API.c b/silk/dec_API.c
+index efd7918..21bb7e0 100644
+--- a/silk/dec_API.c
++++ b/silk/dec_API.c
+@@ -72,6 +72,9 @@ opus_int silk_InitDecoder(                              /* O    Returns error co
+     for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
+         ret  = silk_init_decoder( &channel_state[ n ] );
+     }
++    silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo));
++    /* Not strictly needed, but it's cleaner that way */
++    ((silk_decoder *)decState)->prev_decode_only_middle = 0;
+ 
+     return ret;
+ }
+diff --git a/silk/resampler_private_IIR_FIR.c b/silk/resampler_private_IIR_FIR.c
+index dbd6d9a..91a43aa 100644
+--- a/silk/resampler_private_IIR_FIR.c
++++ b/silk/resampler_private_IIR_FIR.c
+@@ -75,10 +75,10 @@ void silk_resampler_private_IIR_FIR(
+     silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
+     opus_int32 nSamplesIn;
+     opus_int32 max_index_Q16, index_increment_Q16;
+-    opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ];
++    opus_int16 buf[ 2*RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ];
+ 
+     /* Copy buffered samples to start of buffer */
+-    silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
++    silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
+ 
+     /* Iterate over blocks of frameSizeIn input samples */
+     index_increment_Q16 = S->invRatio_Q16;
+@@ -95,13 +95,13 @@ void silk_resampler_private_IIR_FIR(
+ 
+         if( inLen > 0 ) {
+             /* More iterations to do; copy last part of filtered signal to beginning of buffer */
+-            silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
++            silk_memmove( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
+         } else {
+             break;
+         }
+     }
+ 
+     /* Copy last part of filtered signal to the state for the next call */
+-    silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) );
++    silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
+ }
+ 
+diff --git a/src/opus_decoder.c b/src/opus_decoder.c
+index 0cc56f8..8a30fbc 100644
+--- a/src/opus_decoder.c
++++ b/src/opus_decoder.c
+@@ -595,16 +595,14 @@ static int opus_packet_parse_impl(const unsigned char *data, int len,
+       /* Padding flag is bit 6 */
+       if (ch&0x40)
+       {
+-         int padding=0;
+          int p;
+          do {
+             if (len<=0)
+                return OPUS_INVALID_PACKET;
+             p = *data++;
+             len--;
+-            padding += p==255 ? 254: p;
++            len -= p==255 ? 254: p;
+          } while (p==255);
+-         len -= padding;
+       }
+       if (len<0)
+          return OPUS_INVALID_PACKET;
+diff --git a/run_vectors.sh b/run_vectors.sh
+index 7cd23ed..4841b0a 100755
+--- a/run_vectors.sh
++++ b/run_vectors.sh
+@@ -1,3 +1,5 @@
++#!/bin/sh
++#
+ # Copyright (c) 2011-2012 IETF Trust, Jean-Marc Valin. All rights reserved.
+ #
+ #  This file is extracted from RFC6716. Please see that RFC for additional
+@@ -31,10 +33,8 @@
+ #  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ #  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+-#!/bin/sh
+-
+-rm logs_mono.txt
+-rm logs_stereo.txt
++rm -f logs_mono.txt logs_mono2.txt
++rm -f logs_stereo.txt logs_stereo2.txt
+ 
+ if [ "$#" -ne "3" ]; then
+     echo "usage: run_vectors.sh <exec path> <vector path> <rate>"
+@@ -45,18 +45,23 @@ CMD_PATH=$1
+ VECTOR_PATH=$2
+ RATE=$3
+ 
+-OPUS_DEMO=$CMD_PATH/opus_demo
+-OPUS_COMPARE=$CMD_PATH/opus_compare
++: ${OPUS_DEMO:=$CMD_PATH/opus_demo}
++: ${OPUS_COMPARE:=$CMD_PATH/opus_compare}
+ 
+ if [ -d $VECTOR_PATH ]; then
+     echo Test vectors found in $VECTOR_PATH
+ else
+     echo No test vectors found
+-    #Don't make the test fail here because the test vectors will be
+-    #distributed separately
++    #Don't make the test fail here because the test vectors
++    #will be distributed separately
+     exit 0
+ fi
+ 
++if [ ! -x $OPUS_COMPARE ]; then
++    echo ERROR: Compare program not found: $OPUS_COMPARE
++    exit 1
++fi
++
+ if [ -x $OPUS_DEMO ]; then
+     echo Decoding with $OPUS_DEMO
+ else
+@@ -82,9 +87,11 @@ do
+         echo ERROR: decoding failed
+         exit 1
+     fi
+-    $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_mono.txt 2>&1
++    $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector${file}.dec tmp.out >> logs_mono.txt 2>&1
+     float_ret=$?
+-    if [ "$float_ret" -eq "0" ]; then
++    $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector${file}m.dec tmp.out >> logs_mono2.txt 2>&1
++    float_ret2=$?
++    if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
+         echo output matches reference
+     else
+         echo ERROR: output does not match reference
+@@ -111,9 +118,11 @@ do
+         echo ERROR: decoding failed
+         exit 1
+     fi
+-    $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_stereo.txt 2>&1
++    $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector${file}.dec tmp.out >> logs_stereo.txt 2>&1
+     float_ret=$?
+-    if [ "$float_ret" -eq "0" ]; then
++    $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector${file}m.dec tmp.out >> logs_stereo2.txt 2>&1
++    float_ret2=$?
++    if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
+         echo output matches reference
+     else
+         echo ERROR: output does not match reference
+@@ -125,5 +134,10 @@ done
+ 
+ 
+ echo All tests have passed successfully
+-grep quality logs_mono.txt | awk '{sum+=$4}END{print "Average mono quality is", sum/NR, "%"}'
+-grep quality logs_stereo.txt | awk '{sum+=$4}END{print "Average stereo quality is", sum/NR, "%"}'
++mono1=`grep quality logs_mono.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
++mono2=`grep quality logs_mono2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
++echo $mono1 $mono2 | awk '{if ($2 > $1) $1 = $2; print "Average mono quality is", $1, "%"}'
++
++stereo1=`grep quality logs_stereo.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
++stereo2=`grep quality logs_stereo2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
++echo $stereo1 $stereo2 | awk '{if ($2 > $1) $1 = $2; print "Average stereo quality is", $1, "%"}'
diff --git a/doc/release.txt b/doc/release.txt
index 0857839..6d3ffa2 100644
--- a/doc/release.txt
+++ b/doc/release.txt
@@ -4,7 +4,6 @@
 
 - Check for uncommitted changes to master.
 - Update OPUS_LT_* API versioning in configure.ac.
-- Update the version in version.mk
 - Tag the release commit with 'git tag -s vN.M'.
  - Include release notes in the tag annotation.
 - Verify 'make distcheck' produces a tarball with
@@ -16,7 +15,7 @@
  - svn commit
  - Copy to archive.mozilla.org/pub/opus/
  - Update checksum files there as well.
-- Add release notes to https://svn.xiph.org/websites/opus-codec.org/
+- Add release notes to https://git.xiph.org/opus-website.git
 - Update links and checksums on the downloads page.
 - Add a copy of the documentation to <https://www.opus-codec.org/docs/>
   and update the links.
@@ -26,7 +25,7 @@
 which propagates to downloads.xiph.org, and copied manually
 to https://archive.mozilla.org/pub/opus/
 
-Website updates are committed to https://svn.xiph.org/websites/opus-codec.org/
+Website updates are committed to https://git.xiph.org/opus-website.git
 which propagates to https://opus-codec.org/
 
 == Binary release ==
diff --git a/include/opus_defines.h b/include/opus_defines.h
index 315412d..33c5acd 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -165,8 +165,9 @@
 #define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
 #define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
 #define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
-
 /* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
+#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
+#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
 
 /* 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))
@@ -208,6 +209,9 @@
 #define OPUS_FRAMESIZE_20_MS                 5004 /**< Use 20 ms frames */
 #define OPUS_FRAMESIZE_40_MS                 5005 /**< Use 40 ms frames */
 #define OPUS_FRAMESIZE_60_MS                 5006 /**< Use 60 ms frames */
+#define OPUS_FRAMESIZE_80_MS                 5007 /**< Use 80 ms frames */
+#define OPUS_FRAMESIZE_100_MS                5008 /**< Use 100 ms frames */
+#define OPUS_FRAMESIZE_120_MS                5009 /**< Use 120 ms frames */
 
 /**@}*/
 
@@ -566,7 +570,9 @@
   * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
   * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
   * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
-  * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
+  * <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
+  * <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
+  * <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
   * </dl>
   * @hideinitializer */
 #define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
@@ -581,7 +587,9 @@
   * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
   * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
   * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
-  * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
+  * <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
+  * <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
+  * <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
   * </dl>
   * @hideinitializer */
 #define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
@@ -681,6 +689,30 @@
   */
 #define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
 
+/** If set to 1, disables the use of phase inversion for intensity stereo,
+  * improving the quality of mono downmixes, but slightly reducing normal
+  * stereo quality. Disabling phase inversion in the decoder does not comply
+  * with RFC 6716, although it does not cause any interoperability issue and
+  * is expected to become part of the Opus standard once RFC 6716 is updated
+  * by draft-ietf-codec-opus-update.
+  * @see OPUS_GET_PHASE_INVERSION_DISABLED
+  * @param[in] x <tt>opus_int32</tt>: Allowed values:
+  * <dl>
+  * <dt>0</dt><dd>Enable phase inversion (default).</dd>
+  * <dt>1</dt><dd>Disable phase inversion.</dd>
+  * </dl>
+  * @hideinitializer */
+#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured phase inversion status.
+  * @see OPUS_SET_PHASE_INVERSION_DISABLED
+  * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+  * <dl>
+  * <dt>0</dt><dd>Stereo phase inversion enabled (default).</dd>
+  * <dt>1</dt><dd>Stereo phase inversion disabled.</dd>
+  * </dl>
+  * @hideinitializer */
+#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_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 3622e00..babcee6 100644
--- a/include/opus_multistream.h
+++ b/include/opus_multistream.h
@@ -273,7 +273,7 @@
       unsigned char *mapping,
       int application,
       int *error
-) OPUS_ARG_NONNULL(5);
+) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
 
 /** Initialize a previously allocated multistream encoder state.
   * The memory pointed to by \a st must be at least the size returned by
@@ -342,7 +342,7 @@
       int *coupled_streams,
       unsigned char *mapping,
       int application
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7);
 
 /** Encodes a multistream Opus frame.
   * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
diff --git a/include/opus_types.h b/include/opus_types.h
index b28e03a..7180826 100644
--- a/include/opus_types.h
+++ b/include/opus_types.h
@@ -34,7 +34,7 @@
 #define OPUS_TYPES_H
 
 /* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
-#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
+#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
 #include <stdint.h>
 
    typedef int16_t opus_int16;
diff --git a/releases.sha2 b/releases.sha2
index d162ba0..19ce21f 100644
--- a/releases.sha2
+++ b/releases.sha2
@@ -27,6 +27,14 @@
 66f2a5877c8803dc9a5a44b4f3d0bdc8f06bd066324222d144eb255612b68152  opus-1.1.1-rc.tar.gz
 9b84ff56bd7720d5554103c557664efac2b8b18acc4bbcc234cb881ab9a3371e  opus-1.1.1.tar.gz
 0e290078e31211baa7b5886bcc8ab6bc048b9fc83882532da4a1a45e58e907fd  opus-1.1.2.tar.gz
+58b6fe802e7e30182e95d0cde890c0ace40b6f125cffc50635f0ad2eef69b633  opus-1.1.3.tar.gz
+9122b6b380081dd2665189f97bfd777f04f92dc3ab6698eea1dbb27ad59d8692  opus-1.1.4.tar.gz
+eb84981ca0f40a3e5d5e58d2e8582cb2fee05a022825a6dfe14d14b04eb563e4  opus-1.1.5.tar.gz
+654a9bebb73266271a28edcfff431e4cfd9bfcde71f42849a0cdd73bece803a7  opus-1.2-alpha.tar.gz
+c0e90507259cf21ce7b2c82fb9ac55367d8543dae91cc3d4d2c59afd37f44023  opus-1.2-alpha2.tar.gz
+291e979a8a2fb679ed35a5dff5d761a9d9a5e22586fd07934ed94461e2636c7a  opus-1.2-beta.tar.gz
+85343fdaed96529d94c1e1f3a210fa51240d04ca62fa01e97ef02f88020c2ce9  opus-1.2-rc1.tar.gz
+77db45a87b51578fbc49555ef1b10926179861d854eb2613207dc79d9ec0a9a9  opus-1.2.tar.gz
 94ac78ca4f74c4e43bc9fe4ec1ad0aa36f38ab90f45b0727c40dd1e96096e767  opus_testvectors-draft11.tar.gz
 94ac78ca4f74c4e43bc9fe4ec1ad0aa36f38ab90f45b0727c40dd1e96096e767  opus_testvectors.tar.gz
 5d2b99757bcb628bab2611f3ed27af6f35276ce3abc96c0ed4399d6c6463dda5  opus-tools-0.1.2.tar.gz
@@ -37,6 +45,8 @@
 e0f08d301555dffc417604269b5a85d2bd197f259c7d6c957f370ffd33d6d9cd  opus-tools-0.1.7.tar.gz
 e4e188579ea1c4e4d5066460d4a7214a7eafe3539e9a4466fdc98af41ba4a2f6  opus-tools-0.1.8.tar.gz
 b1873dd78c7fbc98cf65d6e10cfddb5c2c03b3af93f922139a2104baedb4643a  opus-tools-0.1.9.tar.gz
+a2357532d19471b70666e0e0ec17d514246d8b3cb2eb168f68bb0f6fd372b28c  opus-tools-0.1.10.tar.gz
+bd6d14e8897a2f80065ef34a516c70e74f8e00060abdbc238e79e5f99bca3e96  libopusenc-0.1.tar.gz
 8071b968475c1a17f54b6840d6de9d9ee20f930e827b0401abe3c4cf4f3bf30a  opusfile-0.1.tar.gz
 b4a678b3b6c4adfb6aff1f67ef658becfe146ea7c7ff228e99543762171557f9  opusfile-0.2.tar.gz
 4248927f2c4e316ea5b84fb02bd100bfec8fa4624a6910d77f0af7f0c6cb8baa  opusfile-0.3.tar.gz
diff --git a/silk/A2NLSF.c b/silk/A2NLSF.c
index b6e9e5f..b487686 100644
--- a/silk/A2NLSF.c
+++ b/silk/A2NLSF.c
@@ -40,7 +40,7 @@
 
 /* Number of binary divisions, when not in low complexity mode */
 #define BIN_DIV_STEPS_A2NLSF_FIX      3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
-#define MAX_ITERATIONS_A2NLSF_FIX    30
+#define MAX_ITERATIONS_A2NLSF_FIX    16
 
 /* Helper function for A2NLSF(..)                    */
 /* Transforms polynomials from cos(n*f) to cos(f)^n  */
@@ -130,7 +130,7 @@
     const opus_int              d                   /* I    Filter order (must be even)                                 */
 )
 {
-    opus_int      i, k, m, dd, root_ix, ffrac;
+    opus_int   i, k, m, dd, root_ix, ffrac;
     opus_int32 xlo, xhi, xmid;
     opus_int32 ylo, yhi, ymid, thr;
     opus_int32 nom, den;
@@ -239,13 +239,13 @@
                     /* Set NLSFs to white spectrum and exit */
                     NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 );
                     for( k = 1; k < d; k++ ) {
-                        NLSF[ k ] = (opus_int16)silk_SMULBB( k + 1, NLSF[ 0 ] );
+                        NLSF[ k ] = (opus_int16)silk_ADD16( NLSF[ k-1 ], NLSF[ 0 ] );
                     }
                     return;
                 }
 
                 /* Error: Apply progressively more bandwidth expansion and run again */
-                silk_bwexpander_32( a_Q16, d, 65536 - silk_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015*/
+                silk_bwexpander_32( a_Q16, d, 65536 - silk_LSHIFT( 1, i ) );
 
                 silk_A2NLSF_init( a_Q16, P, Q, dd );
                 p = P;                            /* Pointer to polynomial */
diff --git a/silk/CNG.c b/silk/CNG.c
index 8443ad6..e6d9b86 100644
--- a/silk/CNG.c
+++ b/silk/CNG.c
@@ -138,11 +138,11 @@
             gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
         }
         gain_Q10 = silk_RSHIFT( gain_Q16, 6 );
-        
+
         silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed );
 
         /* Convert CNG NLSF to filter representation */
-        silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
+        silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order, psDec->arch );
 
         /* Generate CNG signal, by synthesis filtering */
         silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
@@ -170,11 +170,11 @@
             }
 
             /* Update states */
-            CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q14[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
-            
+            CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( CNG_sig_Q14[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
+
             /* Scale with Gain and add to input signal */
             frame[ i ] = (opus_int16)silk_ADD_SAT16( frame[ i ], silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( CNG_sig_Q14[ MAX_LPC_ORDER + i ], gain_Q10 ), 8 ) ) );
-            
+
         }
         silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
     } else {
diff --git a/silk/LPC_analysis_filter.c b/silk/LPC_analysis_filter.c
index 2090667..7715f70 100644
--- a/silk/LPC_analysis_filter.c
+++ b/silk/LPC_analysis_filter.c
@@ -39,6 +39,13 @@
 /* first d output samples are set to zero  */
 /*******************************************/
 
+/* OPT: Using celt_fir() for this function should be faster, but it may cause
+   integer overflows in intermediate values (not final results), which the
+   current implementation silences by casting to unsigned. Enabling
+   this should be safe in pretty much all cases, even though it is not technically
+   C89-compliant. */
+#define USE_CELT_FIR 0
+
 void silk_LPC_analysis_filter(
     opus_int16                  *out,               /* O    Output signal                                               */
     const opus_int16            *in,                /* I    Input signal                                                */
@@ -49,8 +56,7 @@
 )
 {
     opus_int   j;
-#ifdef FIXED_POINT
-    opus_int16 mem[SILK_MAX_ORDER_LPC];
+#if defined(FIXED_POINT) && USE_CELT_FIR
     opus_int16 num[SILK_MAX_ORDER_LPC];
 #else
     int ix;
@@ -62,15 +68,12 @@
     silk_assert( (d & 1) == 0 );
     silk_assert( d <= len );
 
-#ifdef FIXED_POINT
+#if defined(FIXED_POINT) && USE_CELT_FIR
     silk_assert( d <= SILK_MAX_ORDER_LPC );
     for ( j = 0; j < d; j++ ) {
         num[ j ] = -B[ j ];
     }
-    for (j=0;j<d;j++) {
-        mem[ j ] = in[ d - j - 1 ];
-    }
-    celt_fir( in + d, num, out + d, len - d, d, mem, arch );
+    celt_fir( in + d, num, out + d, len - d, d, arch );
     for ( j = 0; j < d; j++ ) {
         out[ j ] = 0;
     }
diff --git a/silk/LPC_fit.c b/silk/LPC_fit.c
new file mode 100644
index 0000000..cdea4f3
--- /dev/null
+++ b/silk/LPC_fit.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+Copyright (c) 2013, Koen Vos. 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FIX.h"
+
+/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
+void silk_LPC_fit(
+    opus_int16                  *a_QOUT,            /* O    Output signal                                               */
+    opus_int32                    *a_QIN,             /* I/O  Input signal                                                */
+    const opus_int              QOUT,               /* I    Input Q domain                                              */
+    const opus_int              QIN,                /* I    Input Q domain                                              */
+    const opus_int              d                   /* I    Filter order                                                */
+)
+{
+    opus_int    i, k, idx = 0;
+    opus_int32    maxabs, absval, chirp_Q16;
+
+    /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
+    for( i = 0; i < 10; i++ ) {
+        /* Find maximum absolute value and its index */
+        maxabs = 0;
+        for( k = 0; k < d; k++ ) {
+            absval = silk_abs( a_QIN[k] );
+            if( absval > maxabs ) {
+                maxabs = absval;
+                idx    = k;
+            }
+        }
+        maxabs = silk_RSHIFT_ROUND( maxabs, QIN - QOUT );
+
+        if( maxabs > silk_int16_MAX ) {
+            /* Reduce magnitude of prediction coefficients */
+            maxabs = silk_min( maxabs, 163838 );  /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
+            chirp_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
+                                        silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
+            silk_bwexpander_32( a_QIN, d, chirp_Q16 );
+        } else {
+            break;
+        }
+    }
+
+    if( i == 10 ) {
+        /* Reached the last iteration, clip the coefficients */
+        for( k = 0; k < d; k++ ) {
+            a_QOUT[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ) );
+            a_QIN[ k ] = silk_LSHIFT( (opus_int32)a_QOUT[ k ], QIN - QOUT );
+        }
+    } else {
+        for( k = 0; k < d; k++ ) {
+            a_QOUT[ k ] = (opus_int16)silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT );
+        }
+    }
+}
diff --git a/silk/LPC_inv_pred_gain.c b/silk/LPC_inv_pred_gain.c
index 4af89aa..a3746a6 100644
--- a/silk/LPC_inv_pred_gain.c
+++ b/silk/LPC_inv_pred_gain.c
@@ -30,6 +30,7 @@
 #endif
 
 #include "SigProc_FIX.h"
+#include "define.h"
 
 #define QA                          24
 #define A_LIMIT                     SILK_FIX_CONST( 0.99975, QA )
@@ -38,117 +39,103 @@
 
 /* Compute inverse of LPC prediction gain, and                          */
 /* test if LPC coefficients are stable (all poles within unit circle)   */
-static opus_int32 LPC_inverse_pred_gain_QA(                 /* O   Returns inverse prediction gain in energy domain, Q30    */
-    opus_int32           A_QA[ 2 ][ SILK_MAX_ORDER_LPC ],   /* I   Prediction coefficients                                  */
+static opus_int32 LPC_inverse_pred_gain_QA_c(               /* O   Returns inverse prediction gain in energy domain, Q30    */
+    opus_int32           A_QA[ SILK_MAX_ORDER_LPC ],        /* I   Prediction coefficients                                  */
     const opus_int       order                              /* I   Prediction order                                         */
 )
 {
     opus_int   k, n, mult2Q;
-    opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA;
-    opus_int32 *Aold_QA, *Anew_QA;
+    opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
 
-    Anew_QA = A_QA[ order & 1 ];
-
-    invGain_Q30 = (opus_int32)1 << 30;
+    invGain_Q30 = SILK_FIX_CONST( 1, 30 );
     for( k = order - 1; k > 0; k-- ) {
         /* Check for stability */
-        if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
+        if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
             return 0;
         }
 
         /* Set RC equal to negated AR coef */
-        rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA );
+        rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
 
         /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
-        rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
+        rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
         silk_assert( rc_mult1_Q30 > ( 1 << 15 ) );                   /* reduce A_LIMIT if fails */
         silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
 
-        /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
-        mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
-        rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
-
         /* Update inverse gain */
         /* invGain_Q30 range: [ 0 : 2^30 ] */
         invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
         silk_assert( invGain_Q30 >= 0           );
         silk_assert( invGain_Q30 <= ( 1 << 30 ) );
+        if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
+            return 0;
+        }
 
-        /* Swap pointers */
-        Aold_QA = Anew_QA;
-        Anew_QA = A_QA[ k & 1 ];
+        /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
+        mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
+        rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
 
         /* Update AR coefficient */
-        for( n = 0; n < k; n++ ) {
-            tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 );
-            Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
+        for( n = 0; n < (k + 1) >> 1; n++ ) {
+            opus_int64 tmp64;
+            tmp1 = A_QA[ n ];
+            tmp2 = A_QA[ k - n - 1 ];
+            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
+                  MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
+            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
+               return 0;
+            }
+            A_QA[ n ] = ( opus_int32 )tmp64;
+            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
+                  MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
+            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
+               return 0;
+            }
+            A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
         }
     }
 
     /* Check for stability */
-    if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
+    if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
         return 0;
     }
 
     /* Set RC equal to negated AR coef */
-    rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA );
+    rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
 
     /* Range: [ 1 : 2^30 ] */
-    rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
+    rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
 
     /* Update inverse gain */
     /* Range: [ 0 : 2^30 ] */
     invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
-    silk_assert( invGain_Q30 >= 0     );
-    silk_assert( invGain_Q30 <= 1<<30 );
+    silk_assert( invGain_Q30 >= 0           );
+    silk_assert( invGain_Q30 <= ( 1 << 30 ) );
+    if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
+        return 0;
+    }
 
     return invGain_Q30;
 }
 
 /* For input in Q12 domain */
-opus_int32 silk_LPC_inverse_pred_gain(              /* O   Returns inverse prediction gain in energy domain, Q30        */
+opus_int32 silk_LPC_inverse_pred_gain_c(            /* O   Returns inverse prediction gain in energy domain, Q30        */
     const opus_int16            *A_Q12,             /* I   Prediction coefficients, Q12 [order]                         */
     const opus_int              order               /* I   Prediction order                                             */
 )
 {
     opus_int   k;
-    opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
-    opus_int32 *Anew_QA;
+    opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
     opus_int32 DC_resp = 0;
 
-    Anew_QA = Atmp_QA[ order & 1 ];
-
     /* Increase Q domain of the AR coefficients */
     for( k = 0; k < order; k++ ) {
         DC_resp += (opus_int32)A_Q12[ k ];
-        Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
+        Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
     }
     /* If the DC is unstable, we don't even need to do the full calculations */
     if( DC_resp >= 4096 ) {
         return 0;
     }
-    return LPC_inverse_pred_gain_QA( Atmp_QA, order );
+    return LPC_inverse_pred_gain_QA_c( Atmp_QA, order );
 }
-
-#ifdef FIXED_POINT
-
-/* For input in Q24 domain */
-opus_int32 silk_LPC_inverse_pred_gain_Q24(          /* O    Returns inverse prediction gain in energy domain, Q30       */
-    const opus_int32            *A_Q24,             /* I    Prediction coefficients [order]                             */
-    const opus_int              order               /* I    Prediction order                                            */
-)
-{
-    opus_int   k;
-    opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
-    opus_int32 *Anew_QA;
-
-    Anew_QA = Atmp_QA[ order & 1 ];
-
-    /* Increase Q domain of the AR coefficients */
-    for( k = 0; k < order; k++ ) {
-        Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
-    }
-
-    return LPC_inverse_pred_gain_QA( Atmp_QA, order );
-}
-#endif
diff --git a/silk/LP_variable_cutoff.c b/silk/LP_variable_cutoff.c
index f639e1f..79112ad 100644
--- a/silk/LP_variable_cutoff.c
+++ b/silk/LP_variable_cutoff.c
@@ -130,6 +130,6 @@
 
         /* ARMA low-pass filtering */
         silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
-        silk_biquad_alt( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length, 1);
+        silk_biquad_alt_stride1( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length);
     }
 }
diff --git a/silk/MacroCount.h b/silk/MacroCount.h
index 834817d..78100ff 100644
--- a/silk/MacroCount.h
+++ b/silk/MacroCount.h
@@ -319,14 +319,6 @@
     return(tmp);
 }
 
-#undef silk_ADD_POS_SAT64
-static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
-    opus_int64 tmp;
-    ops_count += 1;
-    tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
-    return(tmp);
-}
-
 #undef    silk_LSHIFT8
 static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
     opus_int8 ret;
@@ -699,7 +691,7 @@
 
 
 #undef silk_LIMIT_32
-static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
+static OPUS_INLINE opus_int32 silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
 {
     opus_int32 ret;
     ops_count += 6;
diff --git a/silk/MacroDebug.h b/silk/MacroDebug.h
index 35aedc5..8dd4ce2 100644
--- a/silk/MacroDebug.h
+++ b/silk/MacroDebug.h
@@ -539,8 +539,7 @@
    no checking needed for silk_POS_SAT32
    no checking needed for silk_ADD_POS_SAT8
    no checking needed for silk_ADD_POS_SAT16
-   no checking needed for silk_ADD_POS_SAT32
-   no checking needed for silk_ADD_POS_SAT64 */
+   no checking needed for silk_ADD_POS_SAT32 */
 
 #undef silk_LSHIFT8
 #define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
diff --git a/silk/NLSF2A.c b/silk/NLSF2A.c
index b1c559e..116b465 100644
--- a/silk/NLSF2A.c
+++ b/silk/NLSF2A.c
@@ -66,7 +66,8 @@
 void silk_NLSF2A(
     opus_int16                  *a_Q12,             /* O    monic whitening filter coefficients in Q12,  [ d ]          */
     const opus_int16            *NLSF,              /* I    normalized line spectral frequencies in Q15, [ d ]          */
-    const opus_int              d                   /* I    filter order (should be even)                               */
+    const opus_int              d,                  /* I    filter order (should be even)                               */
+    int                         arch                /* I    Run-time architecture                                       */
 )
 {
     /* This ordering was found to maximize quality. It improves numerical accuracy of
@@ -83,15 +84,14 @@
     opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
     opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
     opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
-    opus_int32 maxabs, absval, idx=0, sc_Q16;
 
     silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
-    silk_assert( d==10||d==16 );
+    silk_assert( d==10 || d==16 );
 
     /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
     ordering = d == 16 ? ordering16 : ordering10;
     for( k = 0; k < d; k++ ) {
-        silk_assert(NLSF[k] >= 0 );
+        silk_assert( NLSF[k] >= 0 );
 
         /* f_int on a scale 0-127 (rounded down) */
         f_int = silk_RSHIFT( NLSF[k], 15 - 7 );
@@ -126,52 +126,15 @@
         a32_QA1[ d-k-1 ] =  Qtmp - Ptmp;        /* QA+1 */
     }
 
-    /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
-    for( i = 0; i < 10; i++ ) {
-        /* Find maximum absolute value and its index */
-        maxabs = 0;
-        for( k = 0; k < d; k++ ) {
-            absval = silk_abs( a32_QA1[k] );
-            if( absval > maxabs ) {
-                maxabs = absval;
-                idx    = k;
-            }
-        }
-        maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 );                                          /* QA+1 -> Q12 */
+    /* Convert int32 coefficients to Q12 int16 coefs */
+    silk_LPC_fit( a_Q12, a32_QA1, 12, QA + 1, d );
 
-        if( maxabs > silk_int16_MAX ) {
-            /* Reduce magnitude of prediction coefficients */
-            maxabs = silk_min( maxabs, 163838 );  /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
-            sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
-                                        silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
-            silk_bwexpander_32( a32_QA1, d, sc_Q16 );
-        } else {
-            break;
-        }
-    }
-
-    if( i == 10 ) {
-        /* Reached the last iteration, clip the coefficients */
+    for( i = 0; silk_LPC_inverse_pred_gain( a_Q12, d, arch ) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
+        /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion   */
+        /* on the unscaled coefficients, convert to Q12 and measure again                   */
+        silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
         for( k = 0; k < d; k++ ) {
-            a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) );  /* QA+1 -> Q12 */
-            a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );
-        }
-    } else {
-        for( k = 0; k < d; k++ ) {
-            a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );                /* QA+1 -> Q12 */
-        }
-    }
-
-    for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
-        if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
-            /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion   */
-            /* on the unscaled coefficients, convert to Q12 and measure again                   */
-            silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
-            for( k = 0; k < d; k++ ) {
-                a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );            /* QA+1 -> Q12 */
-            }
-        } else {
-            break;
+            a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 );            /* QA+1 -> Q12 */
         }
     }
 }
diff --git a/silk/NLSF_VQ.c b/silk/NLSF_VQ.c
index 69b6e22..452f3dc 100644
--- a/silk/NLSF_VQ.c
+++ b/silk/NLSF_VQ.c
@@ -33,36 +33,44 @@
 
 /* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
 void silk_NLSF_VQ(
-    opus_int32                  err_Q26[],                      /* O    Quantization errors [K]                     */
+    opus_int32                  err_Q24[],                      /* O    Quantization errors [K]                     */
     const opus_int16            in_Q15[],                       /* I    Input vectors to be quantized [LPC_order]   */
     const opus_uint8            pCB_Q8[],                       /* I    Codebook vectors [K*LPC_order]              */
+    const opus_int16            pWght_Q9[],                     /* I    Codebook weights [K*LPC_order]              */
     const opus_int              K,                              /* I    Number of codebook vectors                  */
     const opus_int              LPC_order                       /* I    Number of LPCs                              */
 )
 {
-    opus_int        i, m;
-    opus_int32      diff_Q15, sum_error_Q30, sum_error_Q26;
+    opus_int         i, m;
+    opus_int32       diff_Q15, diffw_Q24, sum_error_Q24, pred_Q24;
+    const opus_int16 *w_Q9_ptr;
+    const opus_uint8 *cb_Q8_ptr;
 
-    silk_assert( LPC_order <= 16 );
     silk_assert( ( LPC_order & 1 ) == 0 );
 
     /* Loop over codebook */
+    cb_Q8_ptr = pCB_Q8;
+    w_Q9_ptr = pWght_Q9;
     for( i = 0; i < K; i++ ) {
-        sum_error_Q26 = 0;
-        for( m = 0; m < LPC_order; m += 2 ) {
-            /* Compute weighted squared quantization error for index m */
-            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
-            sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );
+        sum_error_Q24 = 0;
+        pred_Q24 = 0;
+        for( m = LPC_order-2; m >= 0; m -= 2 ) {
+            /* Compute weighted absolute predictive quantization error for index m + 1 */
+            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m + 1 ], (opus_int32)cb_Q8_ptr[ m + 1 ], 7 ); /* range: [ -32767 : 32767 ]*/
+            diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m + 1 ] );
+            sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
+            pred_Q24 = diffw_Q24;
 
-            /* Compute weighted squared quantization error for index m + 1 */
-            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
-            sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );
+            /* Compute weighted absolute predictive quantization error for index m */
+            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)cb_Q8_ptr[ m ], 7 ); /* range: [ -32767 : 32767 ]*/
+            diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m ] );
+            sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
+            pred_Q24 = diffw_Q24;
 
-            sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );
-
-            silk_assert( sum_error_Q26 >= 0 );
-            silk_assert( sum_error_Q30 >= 0 );
+            silk_assert( sum_error_Q24 >= 0 );
         }
-        err_Q26[ i ] = sum_error_Q26;
+        err_Q24[ i ] = sum_error_Q24;
+        cb_Q8_ptr += LPC_order;
+        w_Q9_ptr += LPC_order;
     }
 }
diff --git a/silk/NLSF_decode.c b/silk/NLSF_decode.c
index 9f71506..eeb0ba8 100644
--- a/silk/NLSF_decode.c
+++ b/silk/NLSF_decode.c
@@ -32,7 +32,7 @@
 #include "main.h"
 
 /* Predictive dequantizer for NLSF residuals */
-static OPUS_INLINE void silk_NLSF_residual_dequant(               /* O    Returns RD value in Q30                     */
+static OPUS_INLINE void silk_NLSF_residual_dequant(          /* O    Returns RD value in Q30                     */
           opus_int16         x_Q10[],                        /* O    Output [ order ]                            */
     const opus_int8          indices[],                      /* I    Quantization indices [ order ]              */
     const opus_uint8         pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */
@@ -70,15 +70,9 @@
     opus_uint8       pred_Q8[  MAX_LPC_ORDER ];
     opus_int16       ec_ix[    MAX_LPC_ORDER ];
     opus_int16       res_Q10[  MAX_LPC_ORDER ];
-    opus_int16       W_tmp_QW[ MAX_LPC_ORDER ];
-    opus_int32       W_tmp_Q9, NLSF_Q15_tmp;
+    opus_int32       NLSF_Q15_tmp;
     const opus_uint8 *pCB_element;
-
-    /* Decode first stage */
-    pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
-    for( i = 0; i < psNLSF_CB->order; i++ ) {
-        pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );
-    }
+    const opus_int16 *pCB_Wght_Q9;
 
     /* Unpack entropy table indices and predictor for current CB1 index */
     silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );
@@ -86,13 +80,11 @@
     /* Predictive residual dequantizer */
     silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
 
-    /* Weights from codebook vector */
-    silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order );
-
-    /* Apply inverse square-rooted weights and add to output */
+    /* Apply inverse square-rooted weights to first stage and add to output */
+    pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
+    pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
     for( i = 0; i < psNLSF_CB->order; i++ ) {
-        W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
-        NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );
+        NLSF_Q15_tmp = silk_ADD_LSHIFT32( silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), pCB_Wght_Q9[ i ] ), (opus_int16)pCB_element[ i ], 7 );
         pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
     }
 
diff --git a/silk/NLSF_del_dec_quant.c b/silk/NLSF_del_dec_quant.c
index de88fee..44a16ac 100644
--- a/silk/NLSF_del_dec_quant.c
+++ b/silk/NLSF_del_dec_quant.c
@@ -84,7 +84,7 @@
     nStates = 1;
     RD_Q25[ 0 ] = 0;
     prev_out_Q10[ 0 ] = 0;
-    for( i = order - 1; ; i-- ) {
+    for( i = order - 1; i >= 0; i-- ) {
         rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
         in_Q10 = x_Q10[ i ];
         for( j = 0; j < nStates; j++ ) {
@@ -131,7 +131,7 @@
             RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
         }
 
-        if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) {
+        if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
             /* double number of states and copy */
             for( j = 0; j < nStates; j++ ) {
                 ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
@@ -140,7 +140,7 @@
             for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
                 ind[ j ][ i ] = ind[ j - nStates ][ i ];
             }
-        } else if( i > 0 ) {
+        } else {
             /* sort lower and upper half of RD_Q25, pairwise */
             for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
                 if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
@@ -191,8 +191,6 @@
             for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
                 ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
             }
-        } else {  /* i == 0 */
-            break;
         }
     }
 
diff --git a/silk/NLSF_encode.c b/silk/NLSF_encode.c
index f03c3f1..268b9a1 100644
--- a/silk/NLSF_encode.c
+++ b/silk/NLSF_encode.c
@@ -37,9 +37,9 @@
 /***********************/
 opus_int32 silk_NLSF_encode(                                    /* O    Returns RD value in Q25                     */
           opus_int8             *NLSFIndices,                   /* I    Codebook path vector [ LPC_ORDER + 1 ]      */
-          opus_int16            *pNLSF_Q15,                     /* I/O  Quantized NLSF vector [ LPC_ORDER ]         */
+          opus_int16            *pNLSF_Q15,                     /* I/O  (Un)quantized NLSF vector [ LPC_ORDER ]     */
     const silk_NLSF_CB_struct   *psNLSF_CB,                     /* I    Codebook object                             */
-    const opus_int16            *pW_QW,                         /* I    NLSF weight vector [ LPC_ORDER ]            */
+    const opus_int16            *pW_Q2,                         /* I    NLSF weight vector [ LPC_ORDER ]            */
     const opus_int              NLSF_mu_Q20,                    /* I    Rate weight for the RD optimization         */
     const opus_int              nSurvivors,                     /* I    Max survivors after first stage             */
     const opus_int              signalType                      /* I    Signal type: 0/1/2                          */
@@ -47,21 +47,19 @@
 {
     opus_int         i, s, ind1, bestIndex, prob_Q8, bits_q7;
     opus_int32       W_tmp_Q9, ret;
-    VARDECL( opus_int32, err_Q26 );
+    VARDECL( opus_int32, err_Q24 );
     VARDECL( opus_int32, RD_Q25 );
     VARDECL( opus_int, tempIndices1 );
     VARDECL( opus_int8, tempIndices2 );
-    opus_int16       res_Q15[      MAX_LPC_ORDER ];
     opus_int16       res_Q10[      MAX_LPC_ORDER ];
     opus_int16       NLSF_tmp_Q15[ MAX_LPC_ORDER ];
-    opus_int16       W_tmp_QW[     MAX_LPC_ORDER ];
     opus_int16       W_adj_Q5[     MAX_LPC_ORDER ];
     opus_uint8       pred_Q8[      MAX_LPC_ORDER ];
     opus_int16       ec_ix[        MAX_LPC_ORDER ];
     const opus_uint8 *pCB_element, *iCDF_ptr;
+    const opus_int16 *pCB_Wght_Q9;
     SAVE_STACK;
 
-    silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );
     silk_assert( signalType >= 0 && signalType <= 2 );
     silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
 
@@ -69,12 +67,12 @@
     silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
 
     /* First stage: VQ */
-    ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 );
-    silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );
+    ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 );
+    silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order );
 
     /* Sort the quantization errors */
     ALLOC( tempIndices1, nSurvivors, opus_int );
-    silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
+    silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
 
     ALLOC( RD_Q25, nSurvivors, opus_int32 );
     ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
@@ -85,23 +83,12 @@
 
         /* Residual after first stage */
         pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
+        pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ];
         for( i = 0; i < psNLSF_CB->order; i++ ) {
             NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
-            res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ];
-        }
-
-        /* Weights from codebook vector */
-        silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order );
-
-        /* Apply square-rooted weights */
-        for( i = 0; i < psNLSF_CB->order; i++ ) {
-            W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
-            res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
-        }
-
-        /* Modify input weights accordingly */
-        for( i = 0; i < psNLSF_CB->order; i++ ) {
-            W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] );
+            W_tmp_Q9 = pCB_Wght_Q9[ i ];
+            res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 );
+            W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 );
         }
 
         /* Unpack entropy table indices and predictor for current CB1 index */
diff --git a/silk/NSQ.c b/silk/NSQ.c
index 43e3fee..617a19f 100644
--- a/silk/NSQ.c
+++ b/silk/NSQ.c
@@ -37,7 +37,7 @@
 static OPUS_INLINE void silk_nsq_scale_states(
     const silk_encoder_state *psEncC,           /* I    Encoder State                   */
     silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
-    const opus_int32    x_Q3[],                 /* I    input in Q3                     */
+    const opus_int16    x16[],                  /* I    input                           */
     opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */
     const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */
     opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */
@@ -75,14 +75,14 @@
 
 void silk_NSQ_c
 (
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
-    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
+    const opus_int16            x16[],                                        /* I    Input                           */
     opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */
     const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */
     const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */
-    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */
+    const opus_int16            AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs              */
     const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */
     const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */
     const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */
@@ -117,8 +117,7 @@
         LSF_interpolation_flag = 1;
     }
 
-    ALLOC( sLTP_Q15,
-           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+    ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
     ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
     ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
     /* Set up pointers to start of sub frame */
@@ -128,7 +127,7 @@
     for( k = 0; k < psEncC->nb_subfr; k++ ) {
         A_Q12      = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
         B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER ];
-        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];
+        AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
 
         /* Noise shape parameters */
         silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
@@ -154,13 +153,13 @@
             }
         }
 
-        silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
+        silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
 
         silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
             AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
             offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
 
-        x_Q3   += psEncC->subfr_length;
+        x16    += psEncC->subfr_length;
         pulses += psEncC->subfr_length;
         pxq    += psEncC->subfr_length;
     }
@@ -169,7 +168,6 @@
     NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
 
     /* Save quantized speech and noise shaping signals */
-    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
     RESTORE_STACK;
@@ -250,7 +248,7 @@
 
         /* Noise shape feedback */
         silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
-        n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(psLPC_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
+        n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
 
         n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
 
@@ -279,14 +277,27 @@
         r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 );                              /* residual error Q10 */
 
         /* Flip sign depending on dither */
-        if ( NSQ->rand_seed < 0 ) {
-           r_Q10 = -r_Q10;
+        if( NSQ->rand_seed < 0 ) {
+            r_Q10 = -r_Q10;
         }
         r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
 
         /* Find two quantization level candidates and measure their rate-distortion */
         q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
         q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
+        if (Lambda_Q10 > 2048) {
+            /* For aggressive RDO, the bias becomes more than one pulse. */
+            int rdo_offset = Lambda_Q10/2 - 512;
+            if (q1_Q10 > rdo_offset) {
+                q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
+            } else if (q1_Q10 < -rdo_offset) {
+                q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
+            } else if (q1_Q10 < 0) {
+                q1_Q0 = -1;
+            } else {
+                q1_Q0 = 0;
+            }
+        }
         if( q1_Q0 > 0 ) {
             q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
             q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
@@ -337,7 +348,8 @@
         /* Update states */
         psLPC_Q14++;
         *psLPC_Q14 = xq_Q14;
-        sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );
+        NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 );
+        sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 );
         NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
 
         NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
@@ -356,7 +368,7 @@
 static OPUS_INLINE void silk_nsq_scale_states(
     const silk_encoder_state *psEncC,           /* I    Encoder State                   */
     silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
-    const opus_int32    x_Q3[],                 /* I    input in Q3                     */
+    const opus_int16    x16[],                  /* I    input                           */
     opus_int32          x_sc_Q10[],             /* O    input scaled with 1/Gain        */
     const opus_int16    sLTP[],                 /* I    re-whitened LTP state in Q0     */
     opus_int32          sLTP_Q15[],             /* O    LTP state matching scaled input */
@@ -368,28 +380,18 @@
 )
 {
     opus_int   i, lag;
-    opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
+    opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
 
     lag          = pitchL[ subfr ];
     inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
     silk_assert( inv_gain_Q31 != 0 );
 
-    /* Calculate gain adjustment factor */
-    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
-        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
-    } else {
-        gain_adj_Q16 = (opus_int32)1 << 16;
-    }
-
     /* Scale input */
-    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
+    inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
     for( i = 0; i < psEncC->subfr_length; i++ ) {
-        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
+        x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
     }
 
-    /* Save inverse gain */
-    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
-
     /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
     if( NSQ->rewhite_flag ) {
         if( subfr == 0 ) {
@@ -403,7 +405,9 @@
     }
 
     /* Adjust for changing gain */
-    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
+    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
+        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
+
         /* Scale long-term shaping state */
         for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
             NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
@@ -417,6 +421,7 @@
         }
 
         NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
+        NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 );
 
         /* Scale short-term prediction and shaping states */
         for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
@@ -425,5 +430,8 @@
         for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
             NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
         }
+
+        /* Save inverse gain */
+        NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
     }
 }
diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c
index ab6feea..1cd29d9 100644
--- a/silk/NSQ_del_dec.c
+++ b/silk/NSQ_del_dec.c
@@ -43,6 +43,7 @@
     opus_int32 Shape_Q14[ DECISION_DELAY ];
     opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
     opus_int32 LF_AR_Q14;
+    opus_int32 Diff_Q14;
     opus_int32 Seed;
     opus_int32 SeedInit;
     opus_int32 RD_Q10;
@@ -53,6 +54,7 @@
     opus_int32 RD_Q10;
     opus_int32 xq_Q14;
     opus_int32 LF_AR_Q14;
+    opus_int32 Diff_Q14;
     opus_int32 sLTP_shp_Q14;
     opus_int32 LPC_exc_Q14;
 } NSQ_sample_struct;
@@ -66,7 +68,7 @@
     const silk_encoder_state *psEncC,               /* I    Encoder State                       */
     silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */
     NSQ_del_dec_struct  psDelDec[],                 /* I/O  Delayed decision states             */
-    const opus_int32    x_Q3[],                     /* I    Input in Q3                         */
+    const opus_int16    x16[],                      /* I    Input                               */
     opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */
     const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */
     opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */
@@ -107,20 +109,20 @@
     opus_int            predictLPCOrder,        /* I    Prediction filter order             */
     opus_int            warping_Q16,            /* I                                        */
     opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
-    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
     opus_int            decisionDelay,          /* I                                        */
     int                 arch                    /* I                                        */
 );
 
 void silk_NSQ_del_dec_c(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
-    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
+    const opus_int16            x16[],                                        /* I    Input                           */
     opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */
     const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */
     const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */
-    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */
+    const opus_int16            AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs              */
     const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */
     const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */
     const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */
@@ -159,6 +161,7 @@
         psDD->SeedInit       = psDD->Seed;
         psDD->RD_Q10         = 0;
         psDD->LF_AR_Q14      = NSQ->sLF_AR_shp_Q14;
+        psDD->Diff_Q14       = NSQ->sDiff_shp_Q14;
         psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
         silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
         silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
@@ -186,8 +189,7 @@
         LSF_interpolation_flag = 1;
     }
 
-    ALLOC( sLTP_Q15,
-           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+    ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
     ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
     ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
     ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
@@ -199,7 +201,7 @@
     for( k = 0; k < psEncC->nb_subfr; k++ ) {
         A_Q12      = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
         B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER           ];
-        AR_shp_Q13 = &AR2_Q13[     k * MAX_SHAPE_LPC_ORDER ];
+        AR_shp_Q13 = &AR_Q13[     k * MAX_SHAPE_LPC_ORDER ];
 
         /* Noise shape parameters */
         silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
@@ -235,7 +237,8 @@
                     psDD = &psDelDec[ Winner_ind ];
                     last_smple_idx = smpl_buf_idx + decisionDelay;
                     for( i = 0; i < decisionDelay; i++ ) {
-                        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
+                        last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
+                        if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
                         pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
                         pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
                             silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
@@ -257,7 +260,7 @@
             }
         }
 
-        silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
+        silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
             psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
 
         silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
@@ -265,7 +268,7 @@
             Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
             psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch );
 
-        x_Q3   += psEncC->subfr_length;
+        x16    += psEncC->subfr_length;
         pulses += psEncC->subfr_length;
         pxq    += psEncC->subfr_length;
     }
@@ -286,7 +289,9 @@
     last_smple_idx = smpl_buf_idx + decisionDelay;
     Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
     for( i = 0; i < decisionDelay; i++ ) {
-        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
+        last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
+        if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
+
         pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
         pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
             silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
@@ -297,10 +302,10 @@
 
     /* Update states */
     NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
+    NSQ->sDiff_shp_Q14  = psDD->Diff_Q14;
     NSQ->lagPrev        = pitchL[ psEncC->nb_subfr - 1 ];
 
     /* Save quantized speech signal */
-    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
     RESTORE_STACK;
@@ -335,7 +340,7 @@
     opus_int            predictLPCOrder,        /* I    Prediction filter order             */
     opus_int            warping_Q16,            /* I                                        */
     opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
-    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
     opus_int            decisionDelay,          /* I                                        */
     int                 arch                    /* I                                        */
 )
@@ -416,7 +421,7 @@
             /* Noise shape feedback */
             silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
             /* Output of lowpass section */
-            tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
+            tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 );
             /* Output of allpass section */
             tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
             psDD->sAR2_Q14[ 0 ] = tmp2;
@@ -462,6 +467,19 @@
             /* Find two quantization level candidates and measure their rate-distortion */
             q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
             q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
+            if (Lambda_Q10 > 2048) {
+                /* For aggressive RDO, the bias becomes more than one pulse. */
+                int rdo_offset = Lambda_Q10/2 - 512;
+                if (q1_Q10 > rdo_offset) {
+                    q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
+                } else if (q1_Q10 < -rdo_offset) {
+                    q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
+                } else if (q1_Q10 < 0) {
+                    q1_Q0 = -1;
+                } else {
+                    q1_Q0 = 0;
+                }
+            }
             if( q1_Q0 > 0 ) {
                 q1_Q10  = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
                 q1_Q10  = silk_ADD32( q1_Q10, offset_Q10 );
@@ -515,7 +533,8 @@
             xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
 
             /* Update states */
-            sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );
+            psSS[ 0 ].Diff_Q14     = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
+            sLF_AR_shp_Q14         = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 );
             psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
             psSS[ 0 ].LF_AR_Q14    = sLF_AR_shp_Q14;
             psSS[ 0 ].LPC_exc_Q14  = LPC_exc_Q14;
@@ -529,21 +548,22 @@
                 exc_Q14 = -exc_Q14;
             }
 
-
             /* Add predictions */
             LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
             xq_Q14      = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
 
             /* Update states */
-            sLF_AR_shp_Q14         = silk_SUB32( xq_Q14, n_AR_Q14 );
+            psSS[ 1 ].Diff_Q14     = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
+            sLF_AR_shp_Q14         = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 );
             psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
             psSS[ 1 ].LF_AR_Q14    = sLF_AR_shp_Q14;
             psSS[ 1 ].LPC_exc_Q14  = LPC_exc_Q14;
             psSS[ 1 ].xq_Q14       = xq_Q14;
         }
 
-        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */
-        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */
+        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
+        if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
+        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
 
         /* Find winner */
         RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
@@ -607,6 +627,7 @@
             psDD                                     = &psDelDec[ k ];
             psSS                                     = &psSampleState[ k ][ 0 ];
             psDD->LF_AR_Q14                          = psSS->LF_AR_Q14;
+            psDD->Diff_Q14                           = psSS->Diff_Q14;
             psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
             psDD->Xq_Q14[    *smpl_buf_idx ]         = psSS->xq_Q14;
             psDD->Q_Q10[     *smpl_buf_idx ]         = psSS->Q_Q10;
@@ -631,7 +652,7 @@
     const silk_encoder_state *psEncC,               /* I    Encoder State                       */
     silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */
     NSQ_del_dec_struct  psDelDec[],                 /* I/O  Delayed decision states             */
-    const opus_int32    x_Q3[],                     /* I    Input in Q3                         */
+    const opus_int16    x16[],                      /* I    Input                               */
     opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */
     const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */
     opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */
@@ -645,29 +666,19 @@
 )
 {
     opus_int            i, k, lag;
-    opus_int32          gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
+    opus_int32          gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
     NSQ_del_dec_struct  *psDD;
 
     lag          = pitchL[ subfr ];
     inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
     silk_assert( inv_gain_Q31 != 0 );
 
-    /* Calculate gain adjustment factor */
-    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
-        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
-    } else {
-        gain_adj_Q16 = (opus_int32)1 << 16;
-    }
-
     /* Scale input */
-    inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
+    inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
     for( i = 0; i < psEncC->subfr_length; i++ ) {
-        x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
+        x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
     }
 
-    /* Save inverse gain */
-    NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
-
     /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
     if( NSQ->rewhite_flag ) {
         if( subfr == 0 ) {
@@ -681,7 +692,9 @@
     }
 
     /* Adjust for changing gain */
-    if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
+    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
+        gain_adj_Q16 =  silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
+
         /* Scale long-term shaping state */
         for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
             NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
@@ -699,6 +712,7 @@
 
             /* Scale scalar states */
             psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
+            psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 );
 
             /* Scale short-term prediction and shaping states */
             for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
@@ -712,5 +726,8 @@
                 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
             }
         }
+
+        /* Save inverse gain */
+        NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
     }
 }
diff --git a/silk/PLC.c b/silk/PLC.c
index fb6ea88..a3e55ea 100644
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -275,7 +275,7 @@
             /* Reduce random noise for unvoiced frames with high LPC gain */
             opus_int32 invGain_Q30, down_scale_Q30;
 
-            invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order );
+            invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order, arch );
 
             down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
             down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
@@ -328,8 +328,10 @@
         for( j = 0; j < LTP_ORDER; j++ ) {
             B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
         }
-        /* Gradually reduce excitation gain */
-        rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
+        if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) {
+            /* Gradually reduce excitation gain */
+            rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
+        }
 
         /* Slowly increase pitch lag */
         psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h
index b632994..f9ae326 100644
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -35,7 +35,7 @@
 
 /*#define silk_MACRO_COUNT */          /* Used to enable WMOPS counting */
 
-#define SILK_MAX_ORDER_LPC            16            /* max order of the LPC analysis in schur() and k2a() */
+#define SILK_MAX_ORDER_LPC            24            /* max order of the LPC analysis in schur() and k2a() */
 
 #include <string.h>                                 /* for memset(), memcpy(), memmove() */
 #include "typedef.h"
@@ -47,6 +47,11 @@
 #include "x86/SigProc_FIX_sse.h"
 #endif
 
+#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
+#include "arm/biquad_alt_arm.h"
+#include "arm/LPC_inv_pred_gain_arm.h"
+#endif
+
 /********************************************************************/
 /*                    SIGNAL PROCESSING FUNCTIONS                   */
 /********************************************************************/
@@ -96,14 +101,22 @@
  * slower than biquad() but uses more precise coefficients
  * can handle (slowly) varying coefficients
  */
-void silk_biquad_alt(
+void silk_biquad_alt_stride1(
     const opus_int16            *in,                /* I     input signal                                               */
     const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
     const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
     opus_int32                  *S,                 /* I/O   State vector [2]                                           */
     opus_int16                  *out,               /* O     output signal                                              */
-    const opus_int32            len,                /* I     signal length (must be even)                               */
-    opus_int                    stride              /* I     Operate on interleaved signal if > 1                       */
+    const opus_int32            len                 /* I     signal length (must be even)                               */
+);
+
+void silk_biquad_alt_stride2_c(
+    const opus_int16            *in,                /* I     input signal                                               */
+    const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
+    const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
+    opus_int32                  *S,                 /* I/O   State vector [4]                                           */
+    opus_int16                  *out,               /* O     output signal                                              */
+    const opus_int32            len                 /* I     signal length (must be even)                               */
 );
 
 /* Variable order MA prediction error filter. */
@@ -132,17 +145,11 @@
 
 /* Compute inverse of LPC prediction gain, and                           */
 /* test if LPC coefficients are stable (all poles within unit circle)    */
-opus_int32 silk_LPC_inverse_pred_gain(              /* O   Returns inverse prediction gain in energy domain, Q30        */
+opus_int32 silk_LPC_inverse_pred_gain_c(            /* O   Returns inverse prediction gain in energy domain, Q30        */
     const opus_int16            *A_Q12,             /* I   Prediction coefficients, Q12 [order]                         */
     const opus_int              order               /* I   Prediction order                                             */
 );
 
-/* For input in Q24 domain */
-opus_int32 silk_LPC_inverse_pred_gain_Q24(          /* O    Returns inverse prediction gain in energy domain, Q30       */
-    const opus_int32            *A_Q24,             /* I    Prediction coefficients [order]                             */
-    const opus_int              order               /* I    Prediction order                                            */
-);
-
 /* Split signal in two decimated bands using first-order allpass filters */
 void silk_ana_filt_bank_1(
     const opus_int16            *in,                /* I    Input signal [N]                                            */
@@ -152,6 +159,14 @@
     const opus_int32            N                   /* I    Number of input samples                                     */
 );
 
+#if !defined(OVERRIDE_silk_biquad_alt_stride2)
+#define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_c(in, B_Q28, A_Q28, S, out, len))
+#endif
+
+#if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
+#define silk_LPC_inverse_pred_gain(A_Q12, order, arch)     ((void)(arch), silk_LPC_inverse_pred_gain_c(A_Q12, order))
+#endif
+
 /********************************************************************/
 /*                        SCALAR FUNCTIONS                          */
 /********************************************************************/
@@ -271,7 +286,17 @@
 void silk_NLSF2A(
     opus_int16                  *a_Q12,             /* O    monic whitening filter coefficients in Q12,  [ d ]          */
     const opus_int16            *NLSF,              /* I    normalized line spectral frequencies in Q15, [ d ]          */
-    const opus_int              d                   /* I    filter order (should be even)                               */
+    const opus_int              d,                  /* I    filter order (should be even)                               */
+    int                         arch                /* I    Run-time architecture                                       */
+);
+
+/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
+void silk_LPC_fit(
+    opus_int16                  *a_QOUT,            /* O    Output signal                                               */
+    opus_int32                  *a_QIN,             /* I/O  Input signal                                                */
+    const opus_int              QOUT,               /* I    Input Q domain                                              */
+    const opus_int              QIN,                /* I    Input Q domain                                              */
+    const opus_int              d                   /* I    Filter order                                                */
 );
 
 void silk_insertion_sort_increasing(
@@ -471,8 +496,7 @@
 /* Add with saturation for positive input values */
 #define silk_ADD_POS_SAT8(a, b)             ((((a)+(b)) & 0x80)                 ? silk_int8_MAX  : ((a)+(b)))
 #define silk_ADD_POS_SAT16(a, b)            ((((a)+(b)) & 0x8000)               ? silk_int16_MAX : ((a)+(b)))
-#define silk_ADD_POS_SAT32(a, b)            ((((a)+(b)) & 0x80000000)           ? silk_int32_MAX : ((a)+(b)))
-#define silk_ADD_POS_SAT64(a, b)            ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)))
+#define silk_ADD_POS_SAT32(a, b)            ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
 
 #define silk_LSHIFT8(a, shift)              ((opus_int8)((opus_uint8)(a)<<(shift)))         /* shift >= 0, shift < 8  */
 #define silk_LSHIFT16(a, shift)             ((opus_int16)((opus_uint16)(a)<<(shift)))       /* shift >= 0, shift < 16 */
@@ -572,7 +596,9 @@
 /* Make sure to store the result as the seed for the next call (also in between     */
 /* frames), otherwise result won't be random at all. When only using some of the    */
 /* bits, take the most significant bits by right-shifting.                          */
-#define silk_RAND(seed)                     (silk_MLA_ovflw(907633515, (seed), 196314165))
+#define RAND_MULTIPLIER                     196314165
+#define RAND_INCREMENT                      907633515
+#define silk_RAND(seed)                     (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER)))
 
 /*  Add some multiplication functions that can be easily mapped to ARM. */
 
diff --git a/silk/VQ_WMat_EC.c b/silk/VQ_WMat_EC.c
index 7983f1d..0f3d545 100644
--- a/silk/VQ_WMat_EC.c
+++ b/silk/VQ_WMat_EC.c
@@ -34,84 +34,95 @@
 /* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
 void silk_VQ_WMat_EC_c(
     opus_int8                   *ind,                           /* O    index of best codebook vector               */
-    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */
+    opus_int32                  *res_nrg_Q15,                   /* O    best residual energy                        */
+    opus_int32                  *rate_dist_Q8,                  /* O    best total bitrate                          */
     opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */
-    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */
-    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */
+    const opus_int32            *XX_Q17,                        /* I    correlation matrix                          */
+    const opus_int32            *xX_Q17,                        /* I    correlation vector                          */
     const opus_int8             *cb_Q7,                         /* I    codebook                                    */
     const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */
     const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */
-    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */
+    const opus_int              subfr_len,                      /* I    number of samples per subframe              */
     const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */
-    opus_int                    L                               /* I    number of vectors in codebook               */
+    const opus_int              L                               /* I    number of vectors in codebook               */
 )
 {
     opus_int   k, gain_tmp_Q7;
     const opus_int8 *cb_row_Q7;
-    opus_int16 diff_Q14[ 5 ];
-    opus_int32 sum1_Q14, sum2_Q16;
+    opus_int32 neg_xX_Q24[ 5 ];
+    opus_int32 sum1_Q15, sum2_Q24;
+    opus_int32 bits_res_Q8, bits_tot_Q8;
+
+    /* Negate and convert to new Q domain */
+    neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 );
+    neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 );
+    neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 );
+    neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 );
+    neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 );
 
     /* Loop over codebook */
-    *rate_dist_Q14 = silk_int32_MAX;
+    *rate_dist_Q8 = silk_int32_MAX;
+    *res_nrg_Q15 = silk_int32_MAX;
     cb_row_Q7 = cb_Q7;
+    /* In things go really bad, at least *ind is set to something safe. */
+    *ind = 0;
     for( k = 0; k < L; k++ ) {
+        opus_int32 penalty;
         gain_tmp_Q7 = cb_gain_Q7[k];
-
-        diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );
-        diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 );
-        diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 );
-        diff_Q14[ 3 ] = in_Q14[ 3 ] - silk_LSHIFT( cb_row_Q7[ 3 ], 7 );
-        diff_Q14[ 4 ] = in_Q14[ 4 ] - silk_LSHIFT( cb_row_Q7[ 4 ], 7 );
-
         /* Weighted rate */
-        sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );
+        /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */
+        sum1_Q15 = SILK_FIX_CONST( 1.001, 15 );
 
         /* Penalty for too large gain */
-        sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
+        penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 );
 
-        silk_assert( sum1_Q14 >= 0 );
+        /* first row of XX_Q17 */
+        sum2_Q24 = silk_MLA( neg_xX_Q24[ 0 ], XX_Q17[  1 ], cb_row_Q7[ 1 ] );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  2 ], cb_row_Q7[ 2 ] );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  3 ], cb_row_Q7[ 3 ] );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  4 ], cb_row_Q7[ 4 ] );
+        sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  0 ], cb_row_Q7[ 0 ] );
+        sum1_Q15 = silk_SMLAWB( sum1_Q15,        sum2_Q24,  cb_row_Q7[ 0 ] );
 
-        /* first row of W_Q18 */
-        sum2_Q16 = silk_SMULWB(           W_Q18[  1 ], diff_Q14[ 1 ] );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  2 ], diff_Q14[ 2 ] );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  3 ], diff_Q14[ 3 ] );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  4 ], diff_Q14[ 4 ] );
-        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  0 ], diff_Q14[ 0 ] );
-        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 0 ] );
+        /* second row of XX_Q17 */
+        sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[  7 ], cb_row_Q7[ 2 ] );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  8 ], cb_row_Q7[ 3 ] );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  9 ], cb_row_Q7[ 4 ] );
+        sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[  6 ], cb_row_Q7[ 1 ] );
+        sum1_Q15 = silk_SMLAWB( sum1_Q15,        sum2_Q24,  cb_row_Q7[ 1 ] );
 
-        /* second row of W_Q18 */
-        sum2_Q16 = silk_SMULWB(           W_Q18[  7 ], diff_Q14[ 2 ] );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  8 ], diff_Q14[ 3 ] );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  9 ], diff_Q14[ 4 ] );
-        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[  6 ], diff_Q14[ 1 ] );
-        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 1 ] );
+        /* third row of XX_Q17 */
+        sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[ 14 ], cb_row_Q7[ 4 ] );
+        sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[ 12 ], cb_row_Q7[ 2 ] );
+        sum1_Q15 = silk_SMLAWB( sum1_Q15,        sum2_Q24,  cb_row_Q7[ 2 ] );
 
-        /* third row of W_Q18 */
-        sum2_Q16 = silk_SMULWB(           W_Q18[ 13 ], diff_Q14[ 3 ] );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
-        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
-        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 2 ] );
+        /* fourth row of XX_Q17 */
+        sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] );
+        sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[ 18 ], cb_row_Q7[ 3 ] );
+        sum1_Q15 = silk_SMLAWB( sum1_Q15,        sum2_Q24,  cb_row_Q7[ 3 ] );
 
-        /* fourth row of W_Q18 */
-        sum2_Q16 = silk_SMULWB(           W_Q18[ 19 ], diff_Q14[ 4 ] );
-        sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
-        sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
-        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 3 ] );
-
-        /* last row of W_Q18 */
-        sum2_Q16 = silk_SMULWB(           W_Q18[ 24 ], diff_Q14[ 4 ] );
-        sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16,    diff_Q14[ 4 ] );
-
-        silk_assert( sum1_Q14 >= 0 );
+        /* last row of XX_Q17 */
+        sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 );
+        sum2_Q24 = silk_MLA( sum2_Q24,        XX_Q17[ 24 ], cb_row_Q7[ 4 ] );
+        sum1_Q15 = silk_SMLAWB( sum1_Q15,        sum2_Q24,  cb_row_Q7[ 4 ] );
 
         /* find best */
-        if( sum1_Q14 < *rate_dist_Q14 ) {
-            *rate_dist_Q14 = sum1_Q14;
-            *ind = (opus_int8)k;
-            *gain_Q7 = gain_tmp_Q7;
+        if( sum1_Q15 >= 0 ) {
+            /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */
+            bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) );
+            /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */
+            bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 );
+            if( bits_tot_Q8 <= *rate_dist_Q8 ) {
+                *rate_dist_Q8 = bits_tot_Q8;
+                *res_nrg_Q15 = sum1_Q15 + penalty;
+                *ind = (opus_int8)k;
+                *gain_Q7 = gain_tmp_Q7;
+            }
         }
 
         /* Go to next cbk vector */
diff --git a/silk/arm/LPC_inv_pred_gain_arm.h b/silk/arm/LPC_inv_pred_gain_arm.h
new file mode 100644
index 0000000..9895b55
--- /dev/null
+++ b/silk/arm/LPC_inv_pred_gain_arm.h
@@ -0,0 +1,57 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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 SILK_LPC_INV_PRED_GAIN_ARM_H
+# define SILK_LPC_INV_PRED_GAIN_ARM_H
+
+# include "celt/arm/armcpu.h"
+
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+opus_int32 silk_LPC_inverse_pred_gain_neon(         /* O   Returns inverse prediction gain in energy domain, Q30        */
+    const opus_int16            *A_Q12,             /* I   Prediction coefficients, Q12 [order]                         */
+    const opus_int              order               /* I   Prediction order                                             */
+);
+
+#  if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
+#   define OVERRIDE_silk_LPC_inverse_pred_gain            (1)
+#   define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), PRESUME_NEON(silk_LPC_inverse_pred_gain)(A_Q12, order))
+#  endif
+# endif
+
+# if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
+/*Is run-time CPU detection enabled on this platform?*/
+#  if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK+1])(const opus_int16 *A_Q12, const opus_int order);
+#   define OVERRIDE_silk_LPC_inverse_pred_gain            (1)
+#   define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((*SILK_LPC_INVERSE_PRED_GAIN_IMPL[(arch)&OPUS_ARCHMASK])(A_Q12, order))
+#  elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+#   define OVERRIDE_silk_LPC_inverse_pred_gain            (1)
+#   define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_neon(A_Q12, order))
+#  endif
+# endif
+
+#endif /* end SILK_LPC_INV_PRED_GAIN_ARM_H */
diff --git a/silk/arm/LPC_inv_pred_gain_neon_intr.c b/silk/arm/LPC_inv_pred_gain_neon_intr.c
new file mode 100644
index 0000000..27142f3
--- /dev/null
+++ b/silk/arm/LPC_inv_pred_gain_neon_intr.c
@@ -0,0 +1,280 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <arm_neon.h>
+#include "SigProc_FIX.h"
+#include "define.h"
+
+#define QA                          24
+#define A_LIMIT                     SILK_FIX_CONST( 0.99975, QA )
+
+#define MUL32_FRAC_Q(a32, b32, Q)   ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))
+
+/* The difficulty is how to judge a 64-bit signed integer tmp64 is 32-bit overflowed,
+ * since NEON has no 64-bit min, max or comparison instructions.
+ * A failed idea is to compare the results of vmovn(tmp64) and vqmovn(tmp64) whether they are equal or not.
+ * However, this idea fails when the tmp64 is something like 0xFFFFFFF980000000.
+ * Here we know that mult2Q >= 1, so the highest bit (bit 63, sign bit) of tmp64 must equal to bit 62.
+ * tmp64 was shifted left by 1 and we got tmp64'. If high_half(tmp64') != 0 and high_half(tmp64') != -1,
+ * then we know that bit 31 to bit 63 of tmp64 can not all be the sign bit, and therefore tmp64 is 32-bit overflowed.
+ * That is, we judge if tmp64' > 0x00000000FFFFFFFF, or tmp64' <= 0xFFFFFFFF00000000.
+ * We use narrowing shift right 31 bits to tmp32' to save data bandwidth and instructions.
+ * That is, we judge if tmp32' > 0x00000000, or tmp32' <= 0xFFFFFFFF.
+ */
+
+/* Compute inverse of LPC prediction gain, and                          */
+/* test if LPC coefficients are stable (all poles within unit circle)   */
+static OPUS_INLINE opus_int32 LPC_inverse_pred_gain_QA_neon( /* O   Returns inverse prediction gain in energy domain, Q30    */
+    opus_int32           A_QA[ SILK_MAX_ORDER_LPC ],         /* I   Prediction coefficients                                  */
+    const opus_int       order                               /* I   Prediction order                                         */
+)
+{
+    opus_int   k, n, mult2Q;
+    opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
+    opus_int32 max, min;
+    int32x4_t  max_s32x4, min_s32x4;
+    int32x2_t  max_s32x2, min_s32x2;
+
+    max_s32x4 = vdupq_n_s32( silk_int32_MIN );
+    min_s32x4 = vdupq_n_s32( silk_int32_MAX );
+    invGain_Q30 = SILK_FIX_CONST( 1, 30 );
+    for( k = order - 1; k > 0; k-- ) {
+        int32x2_t rc_Q31_s32x2, rc_mult2_s32x2;
+        int64x2_t mult2Q_s64x2;
+
+        /* Check for stability */
+        if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
+            return 0;
+        }
+
+        /* Set RC equal to negated AR coef */
+        rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
+
+        /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
+        rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
+        silk_assert( rc_mult1_Q30 > ( 1 << 15 ) );                   /* reduce A_LIMIT if fails */
+        silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
+
+        /* Update inverse gain */
+        /* invGain_Q30 range: [ 0 : 2^30 ] */
+        invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
+        silk_assert( invGain_Q30 >= 0           );
+        silk_assert( invGain_Q30 <= ( 1 << 30 ) );
+        if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
+            return 0;
+        }
+
+        /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
+        mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
+        rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
+
+        /* Update AR coefficient */
+        rc_Q31_s32x2   = vdup_n_s32( rc_Q31 );
+        mult2Q_s64x2   = vdupq_n_s64( -mult2Q );
+        rc_mult2_s32x2 = vdup_n_s32( rc_mult2 );
+
+        for( n = 0; n < ( ( k + 1 ) >> 1 ) - 3; n += 4 ) {
+            /* We always calculate extra elements of A_QA buffer when ( k % 4 ) != 0, to take the advantage of SIMD parallelization. */
+            int32x4_t tmp1_s32x4, tmp2_s32x4, t0_s32x4, t1_s32x4, s0_s32x4, s1_s32x4, t_QA0_s32x4, t_QA1_s32x4;
+            int64x2_t t0_s64x2, t1_s64x2, t2_s64x2, t3_s64x2;
+            tmp1_s32x4  = vld1q_s32( A_QA + n );
+            tmp2_s32x4  = vld1q_s32( A_QA + k - n - 4 );
+            tmp2_s32x4  = vrev64q_s32( tmp2_s32x4 );
+            tmp2_s32x4  = vcombine_s32( vget_high_s32( tmp2_s32x4 ), vget_low_s32( tmp2_s32x4 ) );
+            t0_s32x4    = vqrdmulhq_lane_s32( tmp2_s32x4, rc_Q31_s32x2, 0 );
+            t1_s32x4    = vqrdmulhq_lane_s32( tmp1_s32x4, rc_Q31_s32x2, 0 );
+            t_QA0_s32x4 = vqsubq_s32( tmp1_s32x4, t0_s32x4 );
+            t_QA1_s32x4 = vqsubq_s32( tmp2_s32x4, t1_s32x4 );
+            t0_s64x2    = vmull_s32( vget_low_s32 ( t_QA0_s32x4 ), rc_mult2_s32x2 );
+            t1_s64x2    = vmull_s32( vget_high_s32( t_QA0_s32x4 ), rc_mult2_s32x2 );
+            t2_s64x2    = vmull_s32( vget_low_s32 ( t_QA1_s32x4 ), rc_mult2_s32x2 );
+            t3_s64x2    = vmull_s32( vget_high_s32( t_QA1_s32x4 ), rc_mult2_s32x2 );
+            t0_s64x2    = vrshlq_s64( t0_s64x2, mult2Q_s64x2 );
+            t1_s64x2    = vrshlq_s64( t1_s64x2, mult2Q_s64x2 );
+            t2_s64x2    = vrshlq_s64( t2_s64x2, mult2Q_s64x2 );
+            t3_s64x2    = vrshlq_s64( t3_s64x2, mult2Q_s64x2 );
+            t0_s32x4    = vcombine_s32( vmovn_s64( t0_s64x2 ), vmovn_s64( t1_s64x2 ) );
+            t1_s32x4    = vcombine_s32( vmovn_s64( t2_s64x2 ), vmovn_s64( t3_s64x2 ) );
+            s0_s32x4    = vcombine_s32( vshrn_n_s64( t0_s64x2, 31 ), vshrn_n_s64( t1_s64x2, 31 ) );
+            s1_s32x4    = vcombine_s32( vshrn_n_s64( t2_s64x2, 31 ), vshrn_n_s64( t3_s64x2, 31 ) );
+            max_s32x4   = vmaxq_s32( max_s32x4, s0_s32x4 );
+            min_s32x4   = vminq_s32( min_s32x4, s0_s32x4 );
+            max_s32x4   = vmaxq_s32( max_s32x4, s1_s32x4 );
+            min_s32x4   = vminq_s32( min_s32x4, s1_s32x4 );
+            t1_s32x4    = vrev64q_s32( t1_s32x4 );
+            t1_s32x4    = vcombine_s32( vget_high_s32( t1_s32x4 ), vget_low_s32( t1_s32x4 ) );
+            vst1q_s32( A_QA + n,         t0_s32x4 );
+            vst1q_s32( A_QA + k - n - 4, t1_s32x4 );
+        }
+        for( ; n < (k + 1) >> 1; n++ ) {
+            opus_int64 tmp64;
+            tmp1 = A_QA[ n ];
+            tmp2 = A_QA[ k - n - 1 ];
+            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
+                  MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
+            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
+               return 0;
+            }
+            A_QA[ n ] = ( opus_int32 )tmp64;
+            tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
+                  MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
+            if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
+               return 0;
+            }
+            A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
+        }
+    }
+
+    /* Check for stability */
+    if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
+        return 0;
+    }
+
+    max_s32x2 = vmax_s32( vget_low_s32( max_s32x4 ), vget_high_s32( max_s32x4 ) );
+    min_s32x2 = vmin_s32( vget_low_s32( min_s32x4 ), vget_high_s32( min_s32x4 ) );
+    max_s32x2 = vmax_s32( max_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( max_s32x2 ), 32 ) ) );
+    min_s32x2 = vmin_s32( min_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( min_s32x2 ), 32 ) ) );
+    max = vget_lane_s32( max_s32x2, 0 );
+    min = vget_lane_s32( min_s32x2, 0 );
+    if( ( max > 0 ) || ( min < -1 ) ) {
+        return 0;
+    }
+
+    /* Set RC equal to negated AR coef */
+    rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
+
+    /* Range: [ 1 : 2^30 ] */
+    rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
+
+    /* Update inverse gain */
+    /* Range: [ 0 : 2^30 ] */
+    invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
+    silk_assert( invGain_Q30 >= 0           );
+    silk_assert( invGain_Q30 <= ( 1 << 30 ) );
+    if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
+        return 0;
+    }
+
+    return invGain_Q30;
+}
+
+/* For input in Q12 domain */
+opus_int32 silk_LPC_inverse_pred_gain_neon(         /* O   Returns inverse prediction gain in energy domain, Q30        */
+    const opus_int16            *A_Q12,             /* I   Prediction coefficients, Q12 [order]                         */
+    const opus_int              order               /* I   Prediction order                                             */
+)
+{
+#ifdef OPUS_CHECK_ASM
+    const opus_int32 invGain_Q30_c = silk_LPC_inverse_pred_gain_c( A_Q12, order );
+#endif
+
+    opus_int32 invGain_Q30;
+    if( ( SILK_MAX_ORDER_LPC != 24 ) || ( order & 1 )) {
+        invGain_Q30 = silk_LPC_inverse_pred_gain_c( A_Q12, order );
+    }
+    else {
+        opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
+        opus_int32 DC_resp;
+        int16x8_t  t0_s16x8, t1_s16x8, t2_s16x8;
+        int32x4_t  t0_s32x4;
+        const opus_int leftover = order & 7;
+
+        /* Increase Q domain of the AR coefficients */
+        t0_s16x8 = vld1q_s16( A_Q12 +  0 );
+        t1_s16x8 = vld1q_s16( A_Q12 +  8 );
+        t2_s16x8 = vld1q_s16( A_Q12 + 16 );
+        t0_s32x4 = vpaddlq_s16( t0_s16x8 );
+
+        switch( order - leftover )
+        {
+        case 24:
+            t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 );
+            /* Intend to fall through */
+
+        case 16:
+            t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 );
+            vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) );
+            vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) );
+            /* Intend to fall through */
+
+        case 8:
+        {
+            const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) );
+            const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 );
+            DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 );
+            vst1q_s32( Atmp_QA +  8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) );
+            vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) );
+        }
+        break;
+
+        default:
+            DC_resp = 0;
+            break;
+        }
+        A_Q12 += order - leftover;
+
+        switch( leftover )
+        {
+        case 6:
+            DC_resp += (opus_int32)A_Q12[ 5 ];
+            DC_resp += (opus_int32)A_Q12[ 4 ];
+            /* Intend to fall through */
+
+        case 4:
+            DC_resp += (opus_int32)A_Q12[ 3 ];
+            DC_resp += (opus_int32)A_Q12[ 2 ];
+            /* Intend to fall through */
+
+        case 2:
+            DC_resp += (opus_int32)A_Q12[ 1 ];
+            DC_resp += (opus_int32)A_Q12[ 0 ];
+            /* Intend to fall through */
+
+        default:
+            break;
+        }
+
+        /* If the DC is unstable, we don't even need to do the full calculations */
+        if( DC_resp >= 4096 ) {
+            invGain_Q30 = 0;
+        } else {
+            vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) );
+            vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) );
+            invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order );
+        }
+    }
+
+#ifdef OPUS_CHECK_ASM
+    silk_assert( invGain_Q30_c == invGain_Q30 );
+#endif
+
+    return invGain_Q30;
+}
diff --git a/silk/arm/NSQ_del_dec_arm.h b/silk/arm/NSQ_del_dec_arm.h
new file mode 100644
index 0000000..9e76e16
--- /dev/null
+++ b/silk/arm/NSQ_del_dec_arm.h
@@ -0,0 +1,100 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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 SILK_NSQ_DEL_DEC_ARM_H
+#define SILK_NSQ_DEL_DEC_ARM_H
+
+#include "celt/arm/armcpu.h"
+
+#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+void silk_NSQ_del_dec_neon(
+    const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
+    SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
+    const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
+    const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
+    const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
+    const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
+    const opus_int Tilt_Q14[MAX_NB_SUBFR],
+    const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
+    const opus_int32 Gains_Q16[MAX_NB_SUBFR],
+    const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
+    const opus_int LTP_scale_Q14);
+
+#if !defined(OPUS_HAVE_RTCD)
+#define OVERRIDE_silk_NSQ_del_dec (1)
+#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12,  \
+                         LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14,   \
+                         LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10,          \
+                         LTP_scale_Q14, arch)                                \
+    ((void)(arch),                                                           \
+     PRESUME_NEON(silk_NSQ_del_dec)(                                         \
+         psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14,     \
+         AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
+         Lambda_Q10, LTP_scale_Q14))
+#endif
+#endif
+
+#if !defined(OVERRIDE_silk_NSQ_del_dec)
+/*Is run-time CPU detection enabled on this platform?*/
+#if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
+                                !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
+    const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
+    SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
+    const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
+    const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
+    const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
+    const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
+    const opus_int Tilt_Q14[MAX_NB_SUBFR],
+    const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
+    const opus_int32 Gains_Q16[MAX_NB_SUBFR],
+    const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
+    const opus_int LTP_scale_Q14);
+#define OVERRIDE_silk_NSQ_del_dec (1)
+#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
+                         LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14,  \
+                         LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10,         \
+                         LTP_scale_Q14, arch)                               \
+    ((*SILK_NSQ_DEL_DEC_IMPL[(arch)&OPUS_ARCHMASK])(                        \
+        psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14,     \
+        AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
+        Lambda_Q10, LTP_scale_Q14))
+#elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+#define OVERRIDE_silk_NSQ_del_dec (1)
+#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12,   \
+                         LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14,    \
+                         LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10,           \
+                         LTP_scale_Q14, arch)                                 \
+    ((void)(arch),                                                            \
+     silk_NSQ_del_dec_neon(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
+                           LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14,  \
+                           LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10,         \
+                           LTP_scale_Q14))
+#endif
+#endif
+
+#endif /* end SILK_NSQ_DEL_DEC_ARM_H */
diff --git a/silk/arm/NSQ_del_dec_neon_intr.c b/silk/arm/NSQ_del_dec_neon_intr.c
new file mode 100644
index 0000000..212410f
--- /dev/null
+++ b/silk/arm/NSQ_del_dec_neon_intr.c
@@ -0,0 +1,1124 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <arm_neon.h>
+#ifdef OPUS_CHECK_ASM
+# include <string.h>
+#endif
+#include "main.h"
+#include "stack_alloc.h"
+
+/* NEON intrinsics optimization now can only parallelize up to 4 delay decision states.    */
+/* If there are more states, C function is called, and this optimization must be expanded. */
+#define NEON_MAX_DEL_DEC_STATES 4
+
+typedef struct {
+    opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ][ NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 RandState[ DECISION_DELAY ][     NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Q_Q10[     DECISION_DELAY ][     NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Xq_Q14[    DECISION_DELAY ][     NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Pred_Q15[  DECISION_DELAY ][     NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Shape_Q14[ DECISION_DELAY ][     NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ][ NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Diff_Q14[  NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Seed[      NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 SeedInit[  NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 RD_Q10[    NEON_MAX_DEL_DEC_STATES ];
+} NSQ_del_decs_struct;
+
+typedef struct {
+    opus_int32 Q_Q10[        NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 RD_Q10[       NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 xq_Q14[       NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 LF_AR_Q14[    NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 Diff_Q14[     NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 sLTP_shp_Q14[ NEON_MAX_DEL_DEC_STATES ];
+    opus_int32 LPC_exc_Q14[  NEON_MAX_DEL_DEC_STATES ];
+} NSQ_samples_struct;
+
+static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
+    const silk_encoder_state *psEncC,               /* I    Encoder State                       */
+    silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */
+    NSQ_del_decs_struct psDelDec[],                 /* I/O  Delayed decision states             */
+    const opus_int16    x16[],                      /* I    Input                               */
+    opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */
+    const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */
+    opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */
+    opus_int            subfr,                      /* I    Subframe number                     */
+    const opus_int      LTP_scale_Q14,              /* I    LTP state scaling                   */
+    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ],  /* I                                        */
+    const opus_int      pitchL[ MAX_NB_SUBFR ],     /* I    Pitch lag                           */
+    const opus_int      signal_type,                /* I    Signal type                         */
+    const opus_int      decisionDelay               /* I    Decision delay                      */
+);
+
+/******************************************/
+/* Noise shape quantizer for one subframe */
+/******************************************/
+static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
+    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */
+    NSQ_del_decs_struct psDelDec[],             /* I/O  Delayed decision states             */
+    opus_int            signalType,             /* I    Signal type                         */
+    const opus_int32    x_Q10[],                /* I                                        */
+    opus_int8           pulses[],               /* O                                        */
+    opus_int16          xq[],                   /* O                                        */
+    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */
+    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */
+    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */
+    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */
+    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */
+    opus_int            lag,                    /* I    Pitch lag                           */
+    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */
+    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */
+    opus_int32          LF_shp_Q14,             /* I                                        */
+    opus_int32          Gain_Q16,               /* I                                        */
+    opus_int            Lambda_Q10,             /* I                                        */
+    opus_int            offset_Q10,             /* I                                        */
+    opus_int            length,                 /* I    Input length                        */
+    opus_int            subfr,                  /* I    Subframe number                     */
+    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */
+    opus_int            predictLPCOrder,        /* I    Prediction filter order             */
+    opus_int            warping_Q16,            /* I                                        */
+    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
+    opus_int            decisionDelay           /* I                                        */
+);
+
+static OPUS_INLINE void copy_winner_state_kernel(
+    const NSQ_del_decs_struct *psDelDec,
+    const opus_int            offset,
+    const opus_int            last_smple_idx,
+    const opus_int            Winner_ind,
+    const int32x2_t           gain_lo_s32x2,
+    const int32x2_t           gain_hi_s32x2,
+    const int32x4_t           shift_s32x4,
+    int32x4_t                 t0_s32x4,
+    int32x4_t                 t1_s32x4,
+    opus_int8 *const          pulses,
+    opus_int16                *pxq,
+    silk_nsq_state            *NSQ
+)
+{
+    int16x8_t t_s16x8;
+    int32x4_t o0_s32x4, o1_s32x4;
+
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
+    t_s16x8 = vcombine_s16( vrshrn_n_s32( t0_s32x4, 10 ), vrshrn_n_s32( t1_s32x4, 10 ) );
+    vst1_s8( &pulses[ offset ], vmovn_s16( t_s16x8 ) );
+
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
+    o0_s32x4 = vqdmulhq_lane_s32( t0_s32x4, gain_lo_s32x2, 0 );
+    o1_s32x4 = vqdmulhq_lane_s32( t1_s32x4, gain_lo_s32x2, 0 );
+    o0_s32x4 = vmlaq_lane_s32( o0_s32x4, t0_s32x4, gain_hi_s32x2, 0 );
+    o1_s32x4 = vmlaq_lane_s32( o1_s32x4, t1_s32x4, gain_hi_s32x2, 0 );
+    o0_s32x4 = vrshlq_s32( o0_s32x4, shift_s32x4 );
+    o1_s32x4 = vrshlq_s32( o1_s32x4, shift_s32x4 );
+    vst1_s16( &pxq[ offset + 0 ], vqmovn_s32( o0_s32x4 ) );
+    vst1_s16( &pxq[ offset + 4 ], vqmovn_s32( o1_s32x4 ) );
+
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
+    t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
+    t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
+    vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 0 ], t0_s32x4 );
+    vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 4 ], t1_s32x4 );
+}
+
+static OPUS_INLINE void copy_winner_state(
+    const NSQ_del_decs_struct *psDelDec,
+    const opus_int            decisionDelay,
+    const opus_int            smpl_buf_idx,
+    const opus_int            Winner_ind,
+    const opus_int32          gain,
+    const opus_int32          shift,
+    opus_int8 *const          pulses,
+    opus_int16                *pxq,
+    silk_nsq_state            *NSQ
+)
+{
+    opus_int        i, last_smple_idx;
+    const int32x2_t gain_lo_s32x2 = vdup_n_s32( silk_LSHIFT32( gain & 0x0000FFFF, 15 ) );
+    const int32x2_t gain_hi_s32x2 = vdup_n_s32( gain >> 16 );
+    const int32x4_t shift_s32x4 = vdupq_n_s32( -shift );
+    int32x4_t       t0_s32x4, t1_s32x4;
+
+    t0_s32x4 = t1_s32x4 = vdupq_n_s32( 0 ); /* initialization */
+    last_smple_idx = smpl_buf_idx + decisionDelay - 1 + DECISION_DELAY;
+    if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
+    if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
+
+    for( i = 0; ( i < ( decisionDelay - 7 ) ) && ( last_smple_idx >= 7 ); i += 8, last_smple_idx -= 8 ) {
+        copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ );
+    }
+    for( ; ( i < decisionDelay ) && ( last_smple_idx >= 0 ); i++, last_smple_idx-- ) {
+        pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
+        pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
+        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
+    }
+
+    last_smple_idx += DECISION_DELAY;
+    for( ; i < ( decisionDelay - 7 ); i++, last_smple_idx-- ) {
+        copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ );
+    }
+    for( ; i < decisionDelay; i++, last_smple_idx-- ) {
+        pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
+        pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
+        NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
+    }
+}
+
+void silk_NSQ_del_dec_neon(
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
+    silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
+    SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
+    const opus_int16            x16[],                                      /* I    Input                           */
+    opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */
+    const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */
+    const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */
+    const opus_int16            AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs              */
+    const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */
+    const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */
+    const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */
+    const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */
+    const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */
+    const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */
+    const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */
+)
+{
+#ifdef OPUS_CHECK_ASM
+    silk_nsq_state NSQ_c;
+    SideInfoIndices psIndices_c;
+    opus_int8 pulses_c[ MAX_FRAME_LENGTH ];
+    const opus_int8 *const pulses_a = pulses;
+
+    ( void )pulses_a;
+    silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) );
+    silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) );
+    silk_memcpy( pulses_c, pulses, sizeof( pulses_c ) );
+    silk_NSQ_del_dec_c( psEncC, &NSQ_c, &psIndices_c, x16, pulses_c, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16,
+                       pitchL, Lambda_Q10, LTP_scale_Q14 );
+#endif
+
+    /* The optimization parallelizes the different delay decision states. */
+    if(( psEncC->nStatesDelayedDecision > NEON_MAX_DEL_DEC_STATES ) || ( psEncC->nStatesDelayedDecision <= 2 )) {
+        /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states.    */
+        /* If there are more states, C function is called, and this optimization must be expanded. */
+        /* When the number of delay decision states is less than 3, there are penalties using this */
+        /* optimization, and C function is called.                                                 */
+        /* When the number of delay decision states is 2, it's better to specialize another        */
+        /* structure NSQ_del_dec2_struct and optimize with shorter NEON registers. (Low priority)  */
+        silk_NSQ_del_dec_c( psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14,
+            Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 );
+    } else {
+        opus_int            i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
+        opus_int            smpl_buf_idx, decisionDelay;
+        const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;
+        opus_int16          *pxq;
+        VARDECL( opus_int32, sLTP_Q15 );
+        VARDECL( opus_int16, sLTP );
+        opus_int32          HarmShapeFIRPacked_Q14;
+        opus_int            offset_Q10;
+        opus_int32          RDmin_Q10, Gain_Q10;
+        VARDECL( opus_int32, x_sc_Q10 );
+        VARDECL( opus_int32, delayedGain_Q10 );
+        VARDECL( NSQ_del_decs_struct, psDelDec );
+        int32x4_t           t_s32x4;
+        SAVE_STACK;
+
+        /* Set unvoiced lag to the previous one, overwrite later for voiced */
+        lag = NSQ->lagPrev;
+
+        silk_assert( NSQ->prev_gain_Q16 != 0 );
+
+        /* Initialize delayed decision states */
+        ALLOC( psDelDec, 1, NSQ_del_decs_struct );
+        /* Only RandState and RD_Q10 need to be initialized to 0. */
+        silk_memset( psDelDec->RandState, 0, sizeof( psDelDec->RandState ) );
+        vst1q_s32( psDelDec->RD_Q10, vdupq_n_s32( 0 ) );
+
+        for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
+            psDelDec->SeedInit[ k ] = psDelDec->Seed[ k ] = ( k + psIndices->Seed ) & 3;
+        }
+        vst1q_s32( psDelDec->LF_AR_Q14, vld1q_dup_s32( &NSQ->sLF_AR_shp_Q14 ) );
+        vst1q_s32( psDelDec->Diff_Q14, vld1q_dup_s32( &NSQ->sDiff_shp_Q14 ) );
+        vst1q_s32( psDelDec->Shape_Q14[ 0 ], vld1q_dup_s32( &NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ] ) );
+        for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
+            vst1q_s32( psDelDec->sLPC_Q14[ i ], vld1q_dup_s32( &NSQ->sLPC_Q14[ i ] ) );
+        }
+        for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
+            vst1q_s32( psDelDec->sAR2_Q14[ i ], vld1q_dup_s32( &NSQ->sAR2_Q14[ i ] ) );
+        }
+
+        offset_Q10   = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
+        smpl_buf_idx = 0; /* index of oldest samples */
+
+        decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
+
+        /* For voiced frames limit the decision delay to lower than the pitch lag */
+        if( psIndices->signalType == TYPE_VOICED ) {
+            opus_int pitch_min = pitchL[ 0 ];
+            for( k = 1; k < psEncC->nb_subfr; k++ ) {
+                pitch_min = silk_min_int( pitch_min, pitchL[ k ] );
+            }
+            decisionDelay = silk_min_int( decisionDelay, pitch_min - LTP_ORDER / 2 - 1 );
+        } else {
+            if( lag > 0 ) {
+                decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
+            }
+        }
+
+        if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
+            LSF_interpolation_flag = 0;
+        } else {
+            LSF_interpolation_flag = 1;
+        }
+
+        ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+        ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
+        ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
+        ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
+        /* Set up pointers to start of sub frame */
+        pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];
+        NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
+        NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;
+        subfr = 0;
+        for( k = 0; k < psEncC->nb_subfr; k++ ) {
+            A_Q12      = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
+            B_Q14      = &LTPCoef_Q14[ k * LTP_ORDER           ];
+            AR_shp_Q13 = &AR_Q13[     k * MAX_SHAPE_LPC_ORDER ];
+
+            /* Noise shape parameters */
+            silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
+            HarmShapeFIRPacked_Q14  =                          silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
+            HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
+
+            NSQ->rewhite_flag = 0;
+            if( psIndices->signalType == TYPE_VOICED ) {
+                /* Voiced */
+                lag = pitchL[ k ];
+
+                /* Re-whitening */
+                if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
+                    if( k == 2 ) {
+                        /* RESET DELAYED DECISIONS */
+                        /* Find winner */
+                        int32x4_t RD_Q10_s32x4;
+                        RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
+                        Winner_ind = 0;
+                        for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
+                            if( psDelDec->RD_Q10[ i ] < RDmin_Q10 ) {
+                                RDmin_Q10 = psDelDec->RD_Q10[ i ];
+                                Winner_ind = i;
+                            }
+                        }
+                        psDelDec->RD_Q10[ Winner_ind ] -= ( silk_int32_MAX >> 4 );
+                        RD_Q10_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
+                        RD_Q10_s32x4 = vaddq_s32( RD_Q10_s32x4, vdupq_n_s32( silk_int32_MAX >> 4 ) );
+                        vst1q_s32( psDelDec->RD_Q10, RD_Q10_s32x4 );
+
+                        /* Copy final part of signals from winner state to output and long-term filter states */
+                        copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gains_Q16[ 1 ], 14, pulses, pxq, NSQ );
+
+                        subfr = 0;
+                    }
+
+                    /* Rewhiten with new A coefs */
+                    start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
+                    silk_assert( start_idx > 0 );
+
+                    silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
+                        A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
+
+                    NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
+                    NSQ->rewhite_flag = 1;
+                }
+            }
+
+            silk_nsq_del_dec_scale_states_neon( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
+                LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
+
+            silk_noise_shape_quantizer_del_dec_neon( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
+                delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
+                Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
+                psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
+
+            x16    += psEncC->subfr_length;
+            pulses += psEncC->subfr_length;
+            pxq    += psEncC->subfr_length;
+        }
+
+        /* Find winner */
+        RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
+        Winner_ind = 0;
+        for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
+            if( psDelDec->RD_Q10[ k ] < RDmin_Q10 ) {
+                RDmin_Q10 = psDelDec->RD_Q10[ k ];
+                Winner_ind = k;
+            }
+        }
+
+        /* Copy final part of signals from winner state to output and long-term filter states */
+        psIndices->Seed = psDelDec->SeedInit[ Winner_ind ];
+        Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
+        copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gain_Q10, 8, pulses, pxq, NSQ );
+
+        t_s32x4 = vdupq_n_s32( 0 ); /* initialization */
+        for( i = 0; i < ( NSQ_LPC_BUF_LENGTH - 3 ); i += 4 ) {
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
+            vst1q_s32( &NSQ->sLPC_Q14[ i ], t_s32x4 );
+        }
+
+        for( ; i < NSQ_LPC_BUF_LENGTH; i++ ) {
+          NSQ->sLPC_Q14[ i ] = psDelDec->sLPC_Q14[ i ][ Winner_ind ];
+        }
+
+        for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) - 3 ); i += 4 ) {
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
+            t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
+            vst1q_s32( &NSQ->sAR2_Q14[ i ], t_s32x4 );
+        }
+
+        for( ; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
+          NSQ->sAR2_Q14[ i ] = psDelDec->sAR2_Q14[ i ][ Winner_ind ];
+        }
+
+        /* Update states */
+        NSQ->sLF_AR_shp_Q14 = psDelDec->LF_AR_Q14[ Winner_ind ];
+        NSQ->sDiff_shp_Q14  = psDelDec->Diff_Q14[ Winner_ind ];
+        NSQ->lagPrev        = pitchL[ psEncC->nb_subfr - 1 ];
+
+        /* Save quantized speech signal */
+        silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
+        silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
+        RESTORE_STACK;
+    }
+
+#ifdef OPUS_CHECK_ASM
+    silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) );
+    silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) );
+    silk_assert( !memcmp( pulses_c, pulses_a, sizeof( pulses_c ) ) );
+#endif
+}
+
+/******************************************/
+/* Noise shape quantizer for one subframe */
+/******************************************/
+/* Note: Function silk_short_prediction_create_arch_coef_neon() defined in NSQ_neon.h is actually a hacking C function. */
+/*       Therefore here we append "_local" to the NEON function name to avoid confusion.                                */
+static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon_local(opus_int32 *out, const opus_int16 *in, opus_int order)
+{
+  int16x8_t t_s16x8;
+  int32x4_t t0_s32x4, t1_s32x4, t2_s32x4, t3_s32x4;
+  silk_assert( order == 10 || order == 16 );
+
+  t_s16x8 = vld1q_s16( in + 0 );                                                   /* 7 6 5 4  3 2 1 0    */
+  t_s16x8 = vrev64q_s16( t_s16x8 );                                                /* 4 5 6 7  0 1 2 3    */
+  t2_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 );                          /* 4 5 6 7             */
+  t3_s32x4 = vshll_n_s16( vget_low_s16(  t_s16x8 ), 15 );                          /* 0 1 2 3             */
+
+  if( order == 16 ) {
+      t_s16x8 = vld1q_s16( in + 8 );                                               /* F E D C  B A 9 8    */
+      t_s16x8 = vrev64q_s16( t_s16x8 );                                            /* C D E F  8 9 A B    */
+      t0_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 );                      /* C D E F             */
+      t1_s32x4 = vshll_n_s16( vget_low_s16(  t_s16x8 ), 15 );                      /* 8 9 A B             */
+  } else {
+      int16x4_t t_s16x4;
+
+      t0_s32x4 = vdupq_n_s32( 0 );                                                 /* zero zero zero zero */
+      t_s16x4 = vld1_s16( in + 6 );                                                /* 9    8    7    6    */
+      t_s16x4 = vrev64_s16( t_s16x4 );                                             /* 6    7    8    9    */
+      t1_s32x4 = vshll_n_s16( t_s16x4, 15 );
+      t1_s32x4 = vcombine_s32( vget_low_s32(t0_s32x4), vget_low_s32( t1_s32x4 ) ); /* 8    9    zero zero */
+  }
+  vst1q_s32( out +  0, t0_s32x4 );
+  vst1q_s32( out +  4, t1_s32x4 );
+  vst1q_s32( out +  8, t2_s32x4 );
+  vst1q_s32( out + 12, t3_s32x4 );
+}
+
+static OPUS_INLINE int32x4_t silk_SMLAWB_lane0_neon(
+    const int32x4_t out_s32x4,
+    const int32x4_t in_s32x4,
+    const int32x2_t coef_s32x2
+)
+{
+    return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 0 ) );
+}
+
+static OPUS_INLINE int32x4_t silk_SMLAWB_lane1_neon(
+    const int32x4_t out_s32x4,
+    const int32x4_t in_s32x4,
+    const int32x2_t coef_s32x2
+)
+{
+    return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 1 ) );
+}
+
+/* Note: This function has different return value than silk_noise_shape_quantizer_short_prediction_neon(). */
+/*       Therefore here we append "_local" to the function name to avoid confusion.                        */
+static OPUS_INLINE int32x4_t silk_noise_shape_quantizer_short_prediction_neon_local(const opus_int32 *buf32, const opus_int32 *a_Q12_arch, opus_int order)
+{
+    const int32x4_t a_Q12_arch0_s32x4 = vld1q_s32( a_Q12_arch + 0 );
+    const int32x4_t a_Q12_arch1_s32x4 = vld1q_s32( a_Q12_arch + 4 );
+    const int32x4_t a_Q12_arch2_s32x4 = vld1q_s32( a_Q12_arch + 8 );
+    const int32x4_t a_Q12_arch3_s32x4 = vld1q_s32( a_Q12_arch + 12 );
+    int32x4_t LPC_pred_Q14_s32x4;
+
+    silk_assert( order == 10 || order == 16 );
+    /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
+    LPC_pred_Q14_s32x4 = vdupq_n_s32( silk_RSHIFT( order, 1 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  0 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch0_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  1 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch0_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  2 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  3 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  4 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch1_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  5 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch1_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  6 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  7 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  8 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch2_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 +  9 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch2_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 10 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 11 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 12 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch3_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 13 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32(  a_Q12_arch3_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 14 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) );
+    LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 15 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) );
+
+    return LPC_pred_Q14_s32x4;
+}
+
+static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
+    silk_nsq_state      *NSQ,                   /* I/O  NSQ state                           */
+    NSQ_del_decs_struct psDelDec[],             /* I/O  Delayed decision states             */
+    opus_int            signalType,             /* I    Signal type                         */
+    const opus_int32    x_Q10[],                /* I                                        */
+    opus_int8           pulses[],               /* O                                        */
+    opus_int16          xq[],                   /* O                                        */
+    opus_int32          sLTP_Q15[],             /* I/O  LTP filter state                    */
+    opus_int32          delayedGain_Q10[],      /* I/O  Gain delay buffer                   */
+    const opus_int16    a_Q12[],                /* I    Short term prediction coefs         */
+    const opus_int16    b_Q14[],                /* I    Long term prediction coefs          */
+    const opus_int16    AR_shp_Q13[],           /* I    Noise shaping coefs                 */
+    opus_int            lag,                    /* I    Pitch lag                           */
+    opus_int32          HarmShapeFIRPacked_Q14, /* I                                        */
+    opus_int            Tilt_Q14,               /* I    Spectral tilt                       */
+    opus_int32          LF_shp_Q14,             /* I                                        */
+    opus_int32          Gain_Q16,               /* I                                        */
+    opus_int            Lambda_Q10,             /* I                                        */
+    opus_int            offset_Q10,             /* I                                        */
+    opus_int            length,                 /* I    Input length                        */
+    opus_int            subfr,                  /* I    Subframe number                     */
+    opus_int            shapingLPCOrder,        /* I    Shaping LPC filter order            */
+    opus_int            predictLPCOrder,        /* I    Prediction filter order             */
+    opus_int            warping_Q16,            /* I                                        */
+    opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
+    opus_int            decisionDelay           /* I                                        */
+)
+{
+    opus_int     i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
+    opus_int32   Winner_rand_state;
+    opus_int32   LTP_pred_Q14, n_LTP_Q14;
+    opus_int32   RDmin_Q10, RDmax_Q10;
+    opus_int32   Gain_Q10;
+    opus_int32   *pred_lag_ptr, *shp_lag_ptr;
+    opus_int32   a_Q12_arch[MAX_LPC_ORDER];
+    const int32x2_t warping_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( warping_Q16, 16 ) >> 1 );
+    const opus_int32 LF_shp_Q29 = silk_LSHIFT32( LF_shp_Q14, 16 ) >> 1;
+    opus_int32 AR_shp_Q28[ MAX_SHAPE_LPC_ORDER ];
+    const uint32x4_t rand_multiplier_u32x4 = vdupq_n_u32( RAND_MULTIPLIER );
+    const uint32x4_t rand_increment_u32x4 = vdupq_n_u32( RAND_INCREMENT );
+
+    VARDECL( NSQ_samples_struct, psSampleState );
+    SAVE_STACK;
+
+    silk_assert( nStatesDelayedDecision > 0 );
+    silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
+    ALLOC( psSampleState, 2, NSQ_samples_struct );
+
+    shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
+    pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
+    Gain_Q10     = silk_RSHIFT( Gain_Q16, 6 );
+
+    for( i = 0; i < ( MAX_SHAPE_LPC_ORDER - 7 ); i += 8 ) {
+      const int16x8_t t_s16x8 = vld1q_s16( AR_shp_Q13 +  i );
+      vst1q_s32( AR_shp_Q28 + i + 0, vshll_n_s16( vget_low_s16(  t_s16x8 ), 15 ) );
+      vst1q_s32( AR_shp_Q28 + i + 4, vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ) );
+    }
+
+    for( ; i < MAX_SHAPE_LPC_ORDER; i++ ) {
+      AR_shp_Q28[i] = silk_LSHIFT32( AR_shp_Q13[i], 15 );
+    }
+
+    silk_short_prediction_create_arch_coef_neon_local( a_Q12_arch, a_Q12, predictLPCOrder );
+
+    for( i = 0; i < length; i++ ) {
+        int32x4_t Seed_s32x4, LPC_pred_Q14_s32x4;
+        int32x4_t sign_s32x4, tmp1_s32x4, tmp2_s32x4;
+        int32x4_t n_AR_Q14_s32x4, n_LF_Q14_s32x4;
+        int32x2_t AR_shp_Q28_s32x2;
+        int16x4_t r_Q10_s16x4, rr_Q10_s16x4;
+
+        /* Perform common calculations used in all states */
+
+        /* Long-term prediction */
+        if( signalType == TYPE_VOICED ) {
+            /* Unrolled loop */
+            /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
+            LTP_pred_Q14 = 2;
+            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[  0 ], b_Q14[ 0 ] );
+            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
+            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
+            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
+            LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
+            LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 );                          /* Q13 -> Q14 */
+            pred_lag_ptr++;
+        } else {
+            LTP_pred_Q14 = 0;
+        }
+
+        /* Long-term shaping */
+        if( lag > 0 ) {
+            /* Symmetric, packed FIR coefficients */
+            n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
+            n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ],                      HarmShapeFIRPacked_Q14 );
+            n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 );            /* Q12 -> Q14 */
+            shp_lag_ptr++;
+        } else {
+            n_LTP_Q14 = 0;
+        }
+
+        /* Generate dither */
+        Seed_s32x4 = vld1q_s32( psDelDec->Seed );
+        Seed_s32x4 = vreinterpretq_s32_u32( vmlaq_u32( rand_increment_u32x4, vreinterpretq_u32_s32( Seed_s32x4 ), rand_multiplier_u32x4 ) );
+        vst1q_s32( psDelDec->Seed, Seed_s32x4 );
+
+        /* Short-term prediction */
+        LPC_pred_Q14_s32x4 = silk_noise_shape_quantizer_short_prediction_neon_local(psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 16 + i ], a_Q12_arch, predictLPCOrder);
+        LPC_pred_Q14_s32x4 = vshlq_n_s32( LPC_pred_Q14_s32x4, 4 ); /* Q10 -> Q14 */
+
+        /* Noise shape feedback */
+        /* Output of lowpass section */
+        tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->Diff_Q14 ), vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), warping_Q16_s32x2 );
+        /* Output of allpass section */
+        tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ 1 ] ), tmp2_s32x4 );
+        tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
+        vst1q_s32( psDelDec->sAR2_Q14[ 0 ], tmp2_s32x4 );
+        AR_shp_Q28_s32x2 = vld1_s32( AR_shp_Q28 );
+        n_AR_Q14_s32x4 = vaddq_s32( vdupq_n_s32( silk_RSHIFT( shapingLPCOrder, 1 ) ), vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
+
+        /* Loop over allpass sections */
+        for( j = 2; j < shapingLPCOrder; j += 2 ) {
+            /* Output of allpass section */
+            tmp2_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4 );
+            tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j - 1 ] ), tmp2_s32x4, warping_Q16_s32x2 );
+            vst1q_s32( psDelDec->sAR2_Q14[ j - 1 ], tmp1_s32x4 );
+            n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
+            /* Output of allpass section */
+            tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 1 ] ), tmp2_s32x4 );
+            tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
+            vst1q_s32( psDelDec->sAR2_Q14[ j + 0 ], tmp2_s32x4 );
+            AR_shp_Q28_s32x2 = vld1_s32( &AR_shp_Q28[ j ] );
+            n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
+        }
+        vst1q_s32( psDelDec->sAR2_Q14[ shapingLPCOrder - 1 ], tmp1_s32x4 );
+        n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
+        n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 1 );                                                                                        /* Q11 -> Q12 */
+        n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( Tilt_Q14, 16 ) >> 1 ) );     /* Q12 */
+        n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 2 );                                                                                        /* Q12 -> Q14 */
+        n_LF_Q14_s32x4 = vqdmulhq_n_s32( vld1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ] ), LF_shp_Q29 );                                         /* Q12 */
+        n_LF_Q14_s32x4 = vaddq_s32( n_LF_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( LF_shp_Q14 >> 16 , 15 ) ) ); /* Q12 */
+        n_LF_Q14_s32x4 = vshlq_n_s32( n_LF_Q14_s32x4, 2 );                                                                                        /* Q12 -> Q14 */
+
+        /* Input minus prediction plus noise feedback                       */
+        /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP  */
+        tmp1_s32x4 = vaddq_s32( n_AR_Q14_s32x4, n_LF_Q14_s32x4 );               /* Q14 */
+        tmp2_s32x4 = vaddq_s32( vdupq_n_s32( n_LTP_Q14 ), LPC_pred_Q14_s32x4 ); /* Q13 */
+        tmp1_s32x4 = vsubq_s32( tmp2_s32x4, tmp1_s32x4 );                       /* Q13 */
+        tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 4 );                             /* Q10 */
+        tmp1_s32x4 = vsubq_s32( vdupq_n_s32( x_Q10[ i ] ), tmp1_s32x4 );        /* residual error Q10 */
+
+        /* Flip sign depending on dither */
+        sign_s32x4 = vreinterpretq_s32_u32( vcltq_s32( Seed_s32x4, vdupq_n_s32( 0 ) ) );
+        tmp1_s32x4 = veorq_s32( tmp1_s32x4, sign_s32x4 );
+        tmp1_s32x4 = vsubq_s32( tmp1_s32x4, sign_s32x4 );
+        tmp1_s32x4 = vmaxq_s32( tmp1_s32x4, vdupq_n_s32( -( 31 << 10 ) ) );
+        tmp1_s32x4 = vminq_s32( tmp1_s32x4, vdupq_n_s32( 30 << 10 ) );
+        r_Q10_s16x4 = vmovn_s32( tmp1_s32x4 );
+
+        /* Find two quantization level candidates and measure their rate-distortion */
+        {
+            int16x4_t q1_Q10_s16x4 = vsub_s16( r_Q10_s16x4, vdup_n_s16( offset_Q10 ) );
+            int16x4_t q1_Q0_s16x4 = vshr_n_s16( q1_Q10_s16x4, 10 );
+            int16x4_t q2_Q10_s16x4;
+            int32x4_t rd1_Q10_s32x4, rd2_Q10_s32x4;
+            uint32x4_t t_u32x4;
+
+            if( Lambda_Q10 > 2048 ) {
+                /* For aggressive RDO, the bias becomes more than one pulse. */
+                const int rdo_offset = Lambda_Q10/2 - 512;
+                const uint16x4_t greaterThanRdo = vcgt_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) );
+                const uint16x4_t lessThanMinusRdo = vclt_s16( q1_Q10_s16x4, vdup_n_s16( -rdo_offset ) );
+                /* If Lambda_Q10 > 32767, then q1_Q0, q1_Q10 and q2_Q10 must change to 32-bit. */
+                silk_assert( Lambda_Q10 <= 32767 );
+
+                q1_Q0_s16x4 = vreinterpret_s16_u16( vclt_s16( q1_Q10_s16x4, vdup_n_s16( 0 ) ) );
+                q1_Q0_s16x4 = vbsl_s16( greaterThanRdo, vsub_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
+                q1_Q0_s16x4 = vbsl_s16( lessThanMinusRdo, vadd_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
+                q1_Q0_s16x4 = vshr_n_s16( q1_Q0_s16x4, 10 );
+            }
+            {
+                const uint16x4_t equal0_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( 0 ) );
+                const uint16x4_t equalMinus1_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
+                const uint16x4_t lessThanMinus1_u16x4 = vclt_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
+                int16x4_t tmp1_s16x4, tmp2_s16x4;
+
+                q1_Q10_s16x4 = vshl_n_s16( q1_Q0_s16x4, 10 );
+                tmp1_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 - QUANT_LEVEL_ADJUST_Q10 ) );
+                q1_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 + QUANT_LEVEL_ADJUST_Q10 ) );
+                q1_Q10_s16x4 = vbsl_s16( lessThanMinus1_u16x4, q1_Q10_s16x4, tmp1_s16x4 );
+                q1_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 ), q1_Q10_s16x4 );
+                q1_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ) ), q1_Q10_s16x4 );
+                q2_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( 1024 ) );
+                q2_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 + 1024 - QUANT_LEVEL_ADJUST_Q10 ), q2_Q10_s16x4 );
+                q2_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 ), q2_Q10_s16x4 );
+                tmp1_s16x4 = q1_Q10_s16x4;
+                tmp2_s16x4 = q2_Q10_s16x4;
+                tmp1_s16x4 = vbsl_s16( vorr_u16( equalMinus1_u16x4, lessThanMinus1_u16x4 ), vneg_s16( tmp1_s16x4 ), tmp1_s16x4 );
+                tmp2_s16x4 = vbsl_s16( lessThanMinus1_u16x4, vneg_s16( tmp2_s16x4 ), tmp2_s16x4 );
+                rd1_Q10_s32x4 = vmull_s16( tmp1_s16x4, vdup_n_s16( Lambda_Q10 ) );
+                rd2_Q10_s32x4 = vmull_s16( tmp2_s16x4, vdup_n_s16( Lambda_Q10 ) );
+            }
+
+            rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q1_Q10_s16x4 );
+            rd1_Q10_s32x4 = vmlal_s16( rd1_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
+            rd1_Q10_s32x4 = vshrq_n_s32( rd1_Q10_s32x4, 10 );
+
+            rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q2_Q10_s16x4 );
+            rd2_Q10_s32x4 = vmlal_s16( rd2_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
+            rd2_Q10_s32x4 = vshrq_n_s32( rd2_Q10_s32x4, 10 );
+
+            tmp2_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
+            tmp1_s32x4 = vaddq_s32( tmp2_s32x4, vminq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
+            tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vmaxq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
+            vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
+            vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
+            t_u32x4 = vcltq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 );
+            tmp1_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q1_Q10_s16x4 ), vmovl_s16( q2_Q10_s16x4 ) );
+            tmp2_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q2_Q10_s16x4 ), vmovl_s16( q1_Q10_s16x4 ) );
+            vst1q_s32( psSampleState[ 0 ].Q_Q10, tmp1_s32x4 );
+            vst1q_s32( psSampleState[ 1 ].Q_Q10, tmp2_s32x4 );
+        }
+
+        {
+            /* Update states for best quantization */
+            int32x4_t exc_Q14_s32x4, LPC_exc_Q14_s32x4, xq_Q14_s32x4, sLF_AR_shp_Q14_s32x4;
+
+            /* Quantized excitation */
+            exc_Q14_s32x4 = vshlq_n_s32( tmp1_s32x4, 4 );
+            exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
+            exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
+
+            /* Add predictions */
+            LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
+            xq_Q14_s32x4      = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
+
+            /* Update states */
+            tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
+            vst1q_s32( psSampleState[ 0 ].Diff_Q14, tmp1_s32x4 );
+            sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
+            vst1q_s32( psSampleState[ 0 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
+            vst1q_s32( psSampleState[ 0 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
+            vst1q_s32( psSampleState[ 0 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
+            vst1q_s32( psSampleState[ 0 ].xq_Q14, xq_Q14_s32x4 );
+
+            /* Quantized excitation */
+            exc_Q14_s32x4 = vshlq_n_s32( tmp2_s32x4, 4 );
+            exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
+            exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
+
+            /* Add predictions */
+            LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
+            xq_Q14_s32x4      = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
+
+            /* Update states */
+            tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
+            vst1q_s32( psSampleState[ 1 ].Diff_Q14, tmp1_s32x4 );
+            sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
+            vst1q_s32( psSampleState[ 1 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
+            vst1q_s32( psSampleState[ 1 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
+            vst1q_s32( psSampleState[ 1 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
+            vst1q_s32( psSampleState[ 1 ].xq_Q14, xq_Q14_s32x4 );
+        }
+
+        *smpl_buf_idx = *smpl_buf_idx ? ( *smpl_buf_idx - 1 ) : ( DECISION_DELAY - 1);
+        last_smple_idx = *smpl_buf_idx + decisionDelay + DECISION_DELAY;
+        if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
+        if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
+
+        /* Find winner */
+        RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
+        Winner_ind = 0;
+        for( k = 1; k < nStatesDelayedDecision; k++ ) {
+            if( psSampleState[ 0 ].RD_Q10[ k ] < RDmin_Q10 ) {
+                RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
+                Winner_ind = k;
+            }
+        }
+
+        /* Increase RD values of expired states */
+        {
+            uint32x4_t t_u32x4;
+            Winner_rand_state = psDelDec->RandState[ last_smple_idx ][ Winner_ind ];
+            t_u32x4 = vceqq_s32( vld1q_s32( psDelDec->RandState[ last_smple_idx ] ), vdupq_n_s32( Winner_rand_state ) );
+            t_u32x4 = vmvnq_u32( t_u32x4 );
+            t_u32x4 = vshrq_n_u32( t_u32x4, 5 );
+            tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].RD_Q10 );
+            tmp2_s32x4 = vld1q_s32( psSampleState[ 1 ].RD_Q10 );
+            tmp1_s32x4 = vaddq_s32( tmp1_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
+            tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
+            vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
+            vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
+
+            /* Find worst in first set and best in second set */
+            RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
+            RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ 0 ];
+            RDmax_ind = 0;
+            RDmin_ind = 0;
+            for( k = 1; k < nStatesDelayedDecision; k++ ) {
+                /* find worst in first set */
+                if( psSampleState[ 0 ].RD_Q10[ k ] > RDmax_Q10 ) {
+                    RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
+                    RDmax_ind = k;
+                }
+                /* find best in second set */
+                if( psSampleState[ 1 ].RD_Q10[ k ] < RDmin_Q10 ) {
+                    RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ k ];
+                    RDmin_ind = k;
+                }
+            }
+        }
+
+        /* Replace a state if best from second set outperforms worst in first set */
+        if( RDmin_Q10 < RDmax_Q10 ) {
+            opus_int32 (*ptr)[NEON_MAX_DEL_DEC_STATES] = psDelDec->RandState;
+            const int numOthers = (int)( ( sizeof( NSQ_del_decs_struct ) - sizeof( ( (NSQ_del_decs_struct *)0 )->sLPC_Q14 ) )
+                / ( NEON_MAX_DEL_DEC_STATES * sizeof( opus_int32 ) ) );
+            /* Only ( predictLPCOrder - 1 ) of sLPC_Q14 buffer need to be updated, though the first several     */
+            /* useless sLPC_Q14[] will be different comparing with C when predictLPCOrder < NSQ_LPC_BUF_LENGTH. */
+            /* Here just update constant ( NSQ_LPC_BUF_LENGTH - 1 ) for simplicity.                             */
+            for( j = i + 1; j < i + NSQ_LPC_BUF_LENGTH; j++ ) {
+                psDelDec->sLPC_Q14[ j ][ RDmax_ind ] = psDelDec->sLPC_Q14[ j ][ RDmin_ind ];
+            }
+            for( j = 0; j < numOthers; j++ ) {
+                ptr[ j ][ RDmax_ind ] = ptr[ j ][ RDmin_ind ];
+            }
+
+            psSampleState[ 0 ].Q_Q10[ RDmax_ind ] = psSampleState[ 1 ].Q_Q10[ RDmin_ind ];
+            psSampleState[ 0 ].RD_Q10[ RDmax_ind ] = psSampleState[ 1 ].RD_Q10[ RDmin_ind ];
+            psSampleState[ 0 ].xq_Q14[ RDmax_ind ] = psSampleState[ 1 ].xq_Q14[ RDmin_ind ];
+            psSampleState[ 0 ].LF_AR_Q14[ RDmax_ind ] = psSampleState[ 1 ].LF_AR_Q14[ RDmin_ind ];
+            psSampleState[ 0 ].Diff_Q14[ RDmax_ind ] = psSampleState[ 1 ].Diff_Q14[ RDmin_ind ];
+            psSampleState[ 0 ].sLTP_shp_Q14[ RDmax_ind ] = psSampleState[ 1 ].sLTP_shp_Q14[ RDmin_ind ];
+            psSampleState[ 0 ].LPC_exc_Q14[ RDmax_ind ] = psSampleState[ 1 ].LPC_exc_Q14[ RDmin_ind ];
+        }
+
+        /* Write samples from winner to output and long-term filter states */
+        if( subfr > 0 || i >= decisionDelay ) {
+            pulses[  i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
+            xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
+                silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
+            NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
+            sLTP_Q15[          NSQ->sLTP_buf_idx     - decisionDelay ] = psDelDec->Pred_Q15[  last_smple_idx ][ Winner_ind ];
+        }
+        NSQ->sLTP_shp_buf_idx++;
+        NSQ->sLTP_buf_idx++;
+
+        /* Update states */
+        vst1q_s32( psDelDec->LF_AR_Q14, vld1q_s32( psSampleState[ 0 ].LF_AR_Q14 ) );
+        vst1q_s32( psDelDec->Diff_Q14, vld1q_s32( psSampleState[ 0 ].Diff_Q14 ) );
+        vst1q_s32( psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
+        vst1q_s32( psDelDec->Xq_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
+        tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].Q_Q10 );
+        vst1q_s32( psDelDec->Q_Q10[ *smpl_buf_idx ], tmp1_s32x4 );
+        vst1q_s32( psDelDec->Pred_Q15[ *smpl_buf_idx ], vshlq_n_s32( vld1q_s32( psSampleState[ 0 ].LPC_exc_Q14 ), 1 ) );
+        vst1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].sLTP_shp_Q14 ) );
+        tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 10 );
+        tmp1_s32x4 = vaddq_s32( vld1q_s32( psDelDec->Seed ), tmp1_s32x4 );
+        vst1q_s32( psDelDec->Seed, tmp1_s32x4 );
+        vst1q_s32( psDelDec->RandState[ *smpl_buf_idx ], tmp1_s32x4 );
+        vst1q_s32( psDelDec->RD_Q10, vld1q_s32( psSampleState[ 0 ].RD_Q10 ) );
+        delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
+    }
+    /* Update LPC states */
+    silk_memcpy( psDelDec->sLPC_Q14[ 0 ], psDelDec->sLPC_Q14[ length ], NEON_MAX_DEL_DEC_STATES * NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
+
+    RESTORE_STACK;
+}
+
+static OPUS_INLINE void silk_SMULWB_8_neon(
+    const opus_int16 *a,
+    const int32x2_t  b,
+    opus_int32       *o
+)
+{
+    const int16x8_t a_s16x8 = vld1q_s16( a );
+    int32x4_t o0_s32x4, o1_s32x4;
+
+    o0_s32x4 = vshll_n_s16( vget_low_s16( a_s16x8 ), 15 );
+    o1_s32x4 = vshll_n_s16( vget_high_s16( a_s16x8 ), 15 );
+    o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b, 0 );
+    o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b, 0 );
+    vst1q_s32( o, o0_s32x4 );
+    vst1q_s32( o + 4, o1_s32x4 );
+}
+
+/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
+static OPUS_INLINE void silk_SMULWW_small_b_4_neon(
+    opus_int32       *a,
+    const int32x2_t  b_s32x2)
+{
+    int32x4_t o_s32x4;
+
+    o_s32x4 = vld1q_s32( a );
+    o_s32x4 = vqdmulhq_lane_s32( o_s32x4, b_s32x2, 0 );
+    vst1q_s32( a, o_s32x4 );
+}
+
+/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
+static OPUS_INLINE void silk_SMULWW_small_b_8_neon(
+    opus_int32       *a,
+    const int32x2_t  b_s32x2
+)
+{
+    int32x4_t o0_s32x4, o1_s32x4;
+
+    o0_s32x4 = vld1q_s32( a );
+    o1_s32x4 = vld1q_s32( a + 4 );
+    o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b_s32x2, 0 );
+    o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b_s32x2, 0 );
+    vst1q_s32( a, o0_s32x4 );
+    vst1q_s32( a + 4, o1_s32x4 );
+}
+
+static OPUS_INLINE void silk_SMULWW_4_neon(
+    opus_int32       *a,
+    const int32x2_t  b_s32x2)
+{
+    int32x4_t a_s32x4, o_s32x4;
+
+    a_s32x4 = vld1q_s32( a );
+    o_s32x4 = vqdmulhq_lane_s32( a_s32x4, b_s32x2, 0 );
+    o_s32x4 = vmlaq_lane_s32( o_s32x4, a_s32x4, b_s32x2, 1 );
+    vst1q_s32( a, o_s32x4 );
+}
+
+static OPUS_INLINE void silk_SMULWW_8_neon(
+    opus_int32       *a,
+    const int32x2_t  b_s32x2
+)
+{
+    int32x4_t a0_s32x4, a1_s32x4, o0_s32x4, o1_s32x4;
+
+    a0_s32x4 = vld1q_s32( a );
+    a1_s32x4 = vld1q_s32( a + 4 );
+    o0_s32x4 = vqdmulhq_lane_s32( a0_s32x4, b_s32x2, 0 );
+    o1_s32x4 = vqdmulhq_lane_s32( a1_s32x4, b_s32x2, 0 );
+    o0_s32x4 = vmlaq_lane_s32( o0_s32x4, a0_s32x4, b_s32x2, 1 );
+    o1_s32x4 = vmlaq_lane_s32( o1_s32x4, a1_s32x4, b_s32x2, 1 );
+    vst1q_s32( a, o0_s32x4 );
+    vst1q_s32( a + 4, o1_s32x4 );
+}
+
+static OPUS_INLINE void silk_SMULWW_loop_neon(
+    const opus_int16 *a,
+    const opus_int32 b,
+    opus_int32       *o,
+    const opus_int   loop_num
+)
+{
+    opus_int i;
+    int32x2_t b_s32x2;
+
+    b_s32x2 = vdup_n_s32( b );
+    for( i = 0; i < loop_num - 7; i += 8 ) {
+        silk_SMULWB_8_neon( a + i, b_s32x2, o + i );
+    }
+    for( ; i < loop_num; i++ ) {
+        o[ i ] = silk_SMULWW( a[ i ], b );
+    }
+}
+
+static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
+    const silk_encoder_state *psEncC,               /* I    Encoder State                       */
+    silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */
+    NSQ_del_decs_struct psDelDec[],                 /* I/O  Delayed decision states             */
+    const opus_int16    x16[],                      /* I    Input                               */
+    opus_int32          x_sc_Q10[],                 /* O    Input scaled with 1/Gain in Q10     */
+    const opus_int16    sLTP[],                     /* I    Re-whitened LTP state in Q0         */
+    opus_int32          sLTP_Q15[],                 /* O    LTP state matching scaled input     */
+    opus_int            subfr,                      /* I    Subframe number                     */
+    const opus_int      LTP_scale_Q14,              /* I    LTP state scaling                   */
+    const opus_int32    Gains_Q16[ MAX_NB_SUBFR ],  /* I                                        */
+    const opus_int      pitchL[ MAX_NB_SUBFR ],     /* I    Pitch lag                           */
+    const opus_int      signal_type,                /* I    Signal type                         */
+    const opus_int      decisionDelay               /* I    Decision delay                      */
+)
+{
+    opus_int            i, lag;
+    opus_int32          gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
+
+    lag          = pitchL[ subfr ];
+    inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
+    silk_assert( inv_gain_Q31 != 0 );
+
+    /* Scale input */
+    inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
+    silk_SMULWW_loop_neon( x16, inv_gain_Q26, x_sc_Q10, psEncC->subfr_length );
+
+    /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
+    if( NSQ->rewhite_flag ) {
+        if( subfr == 0 ) {
+            /* Do LTP downscaling */
+            inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
+        }
+        silk_SMULWW_loop_neon( sLTP + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, inv_gain_Q31, sLTP_Q15 + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, lag + LTP_ORDER / 2 );
+    }
+
+    /* Adjust for changing gain */
+    if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
+        int32x2_t gain_adj_Q16_s32x2;
+        gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
+
+        /* Scale long-term shaping state */
+        if( ( gain_adj_Q16 >= -65536 ) && ( gain_adj_Q16 < 65536 ) ) {
+            gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16, 15 ) );
+            for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
+                silk_SMULWW_small_b_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
+            }
+            for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
+                NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
+            }
+
+            /* Scale long-term prediction state */
+            if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
+                for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
+                    silk_SMULWW_small_b_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
+                }
+                for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
+                    sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
+                }
+            }
+
+            /* Scale scalar states */
+            silk_SMULWW_small_b_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
+            silk_SMULWW_small_b_4_neon( psDelDec->Diff_Q14,  gain_adj_Q16_s32x2 );
+
+            /* Scale short-term prediction and shaping states */
+            for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
+                silk_SMULWW_small_b_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
+            }
+
+            for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
+                silk_SMULWW_small_b_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
+            }
+
+            for( i = 0; i < DECISION_DELAY; i++ ) {
+                silk_SMULWW_small_b_4_neon( psDelDec->Pred_Q15[  i ], gain_adj_Q16_s32x2 );
+                silk_SMULWW_small_b_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
+            }
+        } else {
+            gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16 & 0x0000FFFF, 15 ) );
+            gain_adj_Q16_s32x2 = vset_lane_s32( gain_adj_Q16 >> 16, gain_adj_Q16_s32x2, 1 );
+            for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
+                silk_SMULWW_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
+            }
+            for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
+                NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
+            }
+
+            /* Scale long-term prediction state */
+            if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
+                for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
+                    silk_SMULWW_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
+                }
+                for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
+                    sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
+                }
+            }
+
+            /* Scale scalar states */
+            silk_SMULWW_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
+            silk_SMULWW_4_neon( psDelDec->Diff_Q14,  gain_adj_Q16_s32x2 );
+
+            /* Scale short-term prediction and shaping states */
+            for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
+                silk_SMULWW_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
+            }
+
+            for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
+                silk_SMULWW_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
+            }
+
+            for( i = 0; i < DECISION_DELAY; i++ ) {
+                silk_SMULWW_4_neon( psDelDec->Pred_Q15[  i ], gain_adj_Q16_s32x2 );
+                silk_SMULWW_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
+            }
+        }
+
+        /* Save inverse gain */
+        NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
+    }
+}
diff --git a/silk/arm/NSQ_neon.h b/silk/arm/NSQ_neon.h
index 77c946a..b31d944 100644
--- a/silk/arm/NSQ_neon.h
+++ b/silk/arm/NSQ_neon.h
@@ -28,30 +28,31 @@
 #define SILK_NSQ_NEON_H
 
 #include "cpu_support.h"
+#include "SigProc_FIX.h"
 
 #undef silk_short_prediction_create_arch_coef
 /* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */
 static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order)
 {
-    out[15] = in[0] << 15;
-    out[14] = in[1] << 15;
-    out[13] = in[2] << 15;
-    out[12] = in[3] << 15;
-    out[11] = in[4] << 15;
-    out[10] = in[5] << 15;
-    out[9]  = in[6] << 15;
-    out[8]  = in[7] << 15;
-    out[7]  = in[8] << 15;
-    out[6]  = in[9] << 15;
+    out[15] = silk_LSHIFT32(in[0], 15);
+    out[14] = silk_LSHIFT32(in[1], 15);
+    out[13] = silk_LSHIFT32(in[2], 15);
+    out[12] = silk_LSHIFT32(in[3], 15);
+    out[11] = silk_LSHIFT32(in[4], 15);
+    out[10] = silk_LSHIFT32(in[5], 15);
+    out[9]  = silk_LSHIFT32(in[6], 15);
+    out[8]  = silk_LSHIFT32(in[7], 15);
+    out[7]  = silk_LSHIFT32(in[8], 15);
+    out[6]  = silk_LSHIFT32(in[9], 15);
 
     if (order == 16)
     {
-        out[5] = in[10] << 15;
-        out[4] = in[11] << 15;
-        out[3] = in[12] << 15;
-        out[2] = in[13] << 15;
-        out[1] = in[14] << 15;
-        out[0] = in[15] << 15;
+        out[5] = silk_LSHIFT32(in[10], 15);
+        out[4] = silk_LSHIFT32(in[11], 15);
+        out[3] = silk_LSHIFT32(in[12], 15);
+        out[2] = silk_LSHIFT32(in[13], 15);
+        out[1] = silk_LSHIFT32(in[14], 15);
+        out[0] = silk_LSHIFT32(in[15], 15);
     }
     else
     {
diff --git a/silk/arm/arm_silk_map.c b/silk/arm/arm_silk_map.c
index 9bd86a7..0b9bfec 100644
--- a/silk/arm/arm_silk_map.c
+++ b/silk/arm/arm_silk_map.c
@@ -28,13 +28,62 @@
 # include "config.h"
 #endif
 
+#include "main_FIX.h"
 #include "NSQ.h"
+#include "SigProc_FIX.h"
 
 #if defined(OPUS_HAVE_RTCD)
 
 # if (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
  !defined(OPUS_ARM_PRESUME_NEON_INTR))
 
+void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK + 1])(
+        const opus_int16            *in,                /* I     input signal                                               */
+        const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
+        const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
+        opus_int32                  *S,                 /* I/O   State vector [4]                                           */
+        opus_int16                  *out,               /* O     output signal                                              */
+        const opus_int32            len                 /* I     signal length (must be even)                               */
+) = {
+      silk_biquad_alt_stride2_c,    /* ARMv4 */
+      silk_biquad_alt_stride2_c,    /* EDSP */
+      silk_biquad_alt_stride2_c,    /* Media */
+      silk_biquad_alt_stride2_neon, /* Neon */
+};
+
+opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK + 1])( /* O   Returns inverse prediction gain in energy domain, Q30        */
+        const opus_int16            *A_Q12,                             /* I   Prediction coefficients, Q12 [order]                         */
+        const opus_int              order                               /* I   Prediction order                                             */
+) = {
+      silk_LPC_inverse_pred_gain_c,    /* ARMv4 */
+      silk_LPC_inverse_pred_gain_c,    /* EDSP */
+      silk_LPC_inverse_pred_gain_c,    /* Media */
+      silk_LPC_inverse_pred_gain_neon, /* Neon */
+};
+
+void  (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
+        const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
+        silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
+        SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
+        const opus_int16            x16[],                                      /* I    Input                           */
+        opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */
+        const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */
+        const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */
+        const opus_int16            AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs              */
+        const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */
+        const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */
+        const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */
+        const opus_int32            Gains_Q16[ MAX_NB_SUBFR ],                  /* I    Quantization step sizes         */
+        const opus_int              pitchL[ MAX_NB_SUBFR ],                     /* I    Pitch lags                      */
+        const opus_int              Lambda_Q10,                                 /* I    Rate/distortion tradeoff        */
+        const opus_int              LTP_scale_Q14                               /* I    LTP state scaling               */
+) = {
+      silk_NSQ_del_dec_c,    /* ARMv4 */
+      silk_NSQ_del_dec_c,    /* EDSP */
+      silk_NSQ_del_dec_c,    /* Media */
+      silk_NSQ_del_dec_neon, /* Neon */
+};
+
 /*There is no table for silk_noise_shape_quantizer_short_prediction because the
    NEON version takes different parameters than the C version.
   Instead RTCD is done via if statements at the call sites.
@@ -52,4 +101,23 @@
 
 # endif
 
+# if defined(FIXED_POINT) && \
+ defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
+
+void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK + 1])(
+          opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */
+          opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */
+    const opus_int16                *input,                                 /* I    Input data to correlate                                                     */
+    const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */
+    const opus_int                  length,                                 /* I    Length of input                                                             */
+    const opus_int                  order                                   /* I    Correlation order (even)                                                    */
+) = {
+      silk_warped_autocorrelation_FIX_c,    /* ARMv4 */
+      silk_warped_autocorrelation_FIX_c,    /* EDSP */
+      silk_warped_autocorrelation_FIX_c,    /* Media */
+      silk_warped_autocorrelation_FIX_neon, /* Neon */
+};
+
+# endif
+
 #endif /* OPUS_HAVE_RTCD */
diff --git a/silk/arm/biquad_alt_arm.h b/silk/arm/biquad_alt_arm.h
new file mode 100644
index 0000000..66ea9f4
--- /dev/null
+++ b/silk/arm/biquad_alt_arm.h
@@ -0,0 +1,68 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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 SILK_BIQUAD_ALT_ARM_H
+# define SILK_BIQUAD_ALT_ARM_H
+
+# include "celt/arm/armcpu.h"
+
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+void silk_biquad_alt_stride2_neon(
+    const opus_int16            *in,                /* I     input signal                                               */
+    const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
+    const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
+    opus_int32                  *S,                 /* I/O   State vector [4]                                           */
+    opus_int16                  *out,               /* O     output signal                                              */
+    const opus_int32            len                 /* I     signal length (must be even)                               */
+);
+
+#  if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
+#   define OVERRIDE_silk_biquad_alt_stride2                   (1)
+#   define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), PRESUME_NEON(silk_biquad_alt_stride2)(in, B_Q28, A_Q28, S, out, len))
+#  endif
+# endif
+
+# if !defined(OVERRIDE_silk_biquad_alt_stride2)
+/*Is run-time CPU detection enabled on this platform?*/
+#  if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK+1])(
+        const opus_int16            *in,                /* I     input signal                                               */
+        const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
+        const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
+        opus_int32                  *S,                 /* I/O   State vector [4]                                           */
+        opus_int16                  *out,               /* O     output signal                                              */
+        const opus_int32            len                 /* I     signal length (must be even)                               */
+    );
+#   define OVERRIDE_silk_biquad_alt_stride2                  (1)
+#   define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((*SILK_BIQUAD_ALT_STRIDE2_IMPL[(arch)&OPUS_ARCHMASK])(in, B_Q28, A_Q28, S, out, len))
+#  elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+#   define OVERRIDE_silk_biquad_alt_stride2                  (1)
+#   define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_neon(in, B_Q28, A_Q28, S, out, len))
+#  endif
+# endif
+
+#endif /* end SILK_BIQUAD_ALT_ARM_H */
diff --git a/silk/arm/biquad_alt_neon_intr.c b/silk/arm/biquad_alt_neon_intr.c
new file mode 100644
index 0000000..9715733
--- /dev/null
+++ b/silk/arm/biquad_alt_neon_intr.c
@@ -0,0 +1,156 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <arm_neon.h>
+#ifdef OPUS_CHECK_ASM
+# include <string.h>
+# include "stack_alloc.h"
+#endif
+#include "SigProc_FIX.h"
+
+static inline void silk_biquad_alt_stride2_kernel( const int32x4_t A_L_s32x4, const int32x4_t A_U_s32x4, const int32x4_t B_Q28_s32x4, const int32x2_t t_s32x2, const int32x4_t in_s32x4, int32x4_t *S_s32x4, int32x2_t *out32_Q14_s32x2 )
+{
+    int32x4_t t_s32x4, out32_Q14_s32x4;
+
+    *out32_Q14_s32x2 = vadd_s32( vget_low_s32( *S_s32x4 ), t_s32x2 );              /* silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} )                                      */
+    *S_s32x4         = vcombine_s32( vget_high_s32( *S_s32x4 ), vdup_n_s32( 0 ) ); /* S{0,1} = S{2,3}; S{2,3} = 0;                                                    */
+    *out32_Q14_s32x2 = vshl_n_s32( *out32_Q14_s32x2, 2 );                          /* out32_Q14_{0,1} = silk_LSHIFT( silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ), 2 ); */
+    out32_Q14_s32x4  = vcombine_s32( *out32_Q14_s32x2, *out32_Q14_s32x2 );         /* out32_Q14_{0,1,0,1}                                                             */
+    t_s32x4          = vqdmulhq_s32( out32_Q14_s32x4, A_L_s32x4 );                 /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_L_Q28 )                            */
+    *S_s32x4         = vrsraq_n_s32( *S_s32x4, t_s32x4, 14 );                      /* S{0,1} = S{2,3} + silk_RSHIFT_ROUND();  S{2,3} = silk_RSHIFT_ROUND();           */
+    t_s32x4          = vqdmulhq_s32( out32_Q14_s32x4, A_U_s32x4 );                 /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 )                            */
+    *S_s32x4         = vaddq_s32( *S_s32x4, t_s32x4 );                             /* S0 = silk_SMLAWB( S{0,1,2,3}, out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 );          */
+    t_s32x4          = vqdmulhq_s32( in_s32x4, B_Q28_s32x4 );                      /* silk_SMULWB( B_Q28[ {1,1,2,2} ], in{0,1,0,1} )                                  */
+    *S_s32x4         = vaddq_s32( *S_s32x4, t_s32x4 );                             /* S0 = silk_SMLAWB( S0, B_Q28[ {1,1,2,2} ], in{0,1,0,1} );                        */
+}
+
+void silk_biquad_alt_stride2_neon(
+    const opus_int16            *in,                /* I     input signal                                               */
+    const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
+    const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
+    opus_int32                  *S,                 /* I/O   State vector [4]                                           */
+    opus_int16                  *out,               /* O     output signal                                              */
+    const opus_int32            len                 /* I     signal length (must be even)                               */
+)
+{
+    /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
+    opus_int        k            = 0;
+    const int32x2_t offset_s32x2 = vdup_n_s32( (1<<14) - 1 );
+    const int32x4_t offset_s32x4 = vcombine_s32( offset_s32x2, offset_s32x2 );
+    int16x4_t       in_s16x4  = vdup_n_s16( 0 );
+    int16x4_t       out_s16x4;
+    int32x2_t       A_Q28_s32x2, A_L_s32x2, A_U_s32x2, B_Q28_s32x2, t_s32x2;
+    int32x4_t       A_L_s32x4, A_U_s32x4, B_Q28_s32x4, S_s32x4, out32_Q14_s32x4;
+    int32x2x2_t     t0_s32x2x2, t1_s32x2x2, t2_s32x2x2, S_s32x2x2;
+
+#ifdef OPUS_CHECK_ASM
+    opus_int32 S_c[ 4 ];
+    VARDECL( opus_int16, out_c );
+    SAVE_STACK;
+    ALLOC( out_c, 2 * len, opus_int16 );
+
+    silk_memcpy( &S_c, S, sizeof( S_c ) );
+    silk_biquad_alt_stride2_c( in, B_Q28, A_Q28, S_c, out_c, len );
+#endif
+
+    /* Negate A_Q28 values and split in two parts */
+    A_Q28_s32x2 = vld1_s32( A_Q28 );
+    A_Q28_s32x2 = vneg_s32( A_Q28_s32x2 );
+    A_L_s32x2   = vshl_n_s32( A_Q28_s32x2, 18 );                                                        /* ( -A_Q28[] & 0x00003FFF ) << 18                                                     */
+    A_L_s32x2   = vreinterpret_s32_u32( vshr_n_u32( vreinterpret_u32_s32( A_L_s32x2 ), 3 ) );           /* ( -A_Q28[] & 0x00003FFF ) << 15                                                     */
+    A_U_s32x2   = vshr_n_s32( A_Q28_s32x2, 14 );                                                        /* silk_RSHIFT( -A_Q28[], 14 )                                                         */
+    A_U_s32x2   = vshl_n_s32( A_U_s32x2, 16 );                                                          /* silk_RSHIFT( -A_Q28[], 14 ) << 16 (Clip two leading bits to conform to C function.) */
+    A_U_s32x2   = vshr_n_s32( A_U_s32x2, 1 );                                                           /* silk_RSHIFT( -A_Q28[], 14 ) << 15                                                   */
+
+    B_Q28_s32x2  = vld1_s32( B_Q28 );
+    t_s32x2      = vld1_s32( B_Q28 + 1 );
+    t0_s32x2x2   = vzip_s32( A_L_s32x2, A_L_s32x2 );
+    t1_s32x2x2   = vzip_s32( A_U_s32x2, A_U_s32x2 );
+    t2_s32x2x2   = vzip_s32( t_s32x2, t_s32x2 );
+    A_L_s32x4    = vcombine_s32( t0_s32x2x2.val[ 0 ], t0_s32x2x2.val[ 1 ] );                            /* A{0,0,1,1}_L_Q28          */
+    A_U_s32x4    = vcombine_s32( t1_s32x2x2.val[ 0 ], t1_s32x2x2.val[ 1 ] );                            /* A{0,0,1,1}_U_Q28          */
+    B_Q28_s32x4  = vcombine_s32( t2_s32x2x2.val[ 0 ], t2_s32x2x2.val[ 1 ] );                            /* B_Q28[ {1,1,2,2} ]        */
+    S_s32x4      = vld1q_s32( S );                                                                      /* S0 = S[ 0 ]; S3 = S[ 3 ]; */
+    S_s32x2x2    = vtrn_s32( vget_low_s32( S_s32x4 ), vget_high_s32( S_s32x4 ) );                       /* S2 = S[ 1 ]; S1 = S[ 2 ]; */
+    S_s32x4      = vcombine_s32( S_s32x2x2.val[ 0 ], S_s32x2x2.val[ 1 ] );
+
+    for( ; k < len - 1; k += 2 ) {
+        int32x4_t in_s32x4[ 2 ], t_s32x4;
+        int32x2_t out32_Q14_s32x2[ 2 ];
+
+        /* S[ 2 * i + 0 ], S[ 2 * i + 1 ], S[ 2 * i + 2 ], S[ 2 * i + 3 ]: Q12 */
+        in_s16x4      = vld1_s16( &in[ 2 * k ] );                                                       /* in{0,1,2,3} = in[ 2 * k + {0,1,2,3} ]; */
+        in_s32x4[ 0 ] = vshll_n_s16( in_s16x4, 15 );                                                    /* in{0,1,2,3} << 15                      */
+        t_s32x4       = vqdmulhq_lane_s32( in_s32x4[ 0 ], B_Q28_s32x2, 0 );                             /* silk_SMULWB( B_Q28[ 0 ], in{0,1,2,3} ) */
+        in_s32x4[ 1 ] = vcombine_s32( vget_high_s32( in_s32x4[ 0 ] ), vget_high_s32( in_s32x4[ 0 ] ) ); /* in{2,3,2,3} << 15                      */
+        in_s32x4[ 0 ] = vcombine_s32( vget_low_s32 ( in_s32x4[ 0 ] ), vget_low_s32 ( in_s32x4[ 0 ] ) ); /* in{0,1,0,1} << 15                      */
+        silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_low_s32 ( t_s32x4 ), in_s32x4[ 0 ], &S_s32x4, &out32_Q14_s32x2[ 0 ] );
+        silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_high_s32( t_s32x4 ), in_s32x4[ 1 ], &S_s32x4, &out32_Q14_s32x2[ 1 ] );
+
+        /* Scale back to Q0 and saturate */
+        out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2[ 0 ], out32_Q14_s32x2[ 1 ] );                   /* out32_Q14_{0,1,2,3}                                                                                        */
+        out32_Q14_s32x4 = vaddq_s32( out32_Q14_s32x4, offset_s32x4 );                                   /* out32_Q14_{0,1,2,3} + (1<<14) - 1                                                                          */
+        out_s16x4       = vqshrn_n_s32( out32_Q14_s32x4, 14 );                                          /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) )                             */
+        vst1_s16( &out[ 2 * k ], out_s16x4 );                                                           /* out[ 2 * k + {0,1,2,3} ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ); */
+    }
+
+    /* Process leftover. */
+    if( k < len ) {
+        int32x4_t in_s32x4;
+        int32x2_t out32_Q14_s32x2;
+
+        /* S[ 2 * i + 0 ], S[ 2 * i + 1 ]: Q12 */
+        in_s16x4     = vld1_lane_s16( &in[ 2 * k + 0 ], in_s16x4, 0 );                                  /* in{0,1} = in[ 2 * k + {0,1} ];     */
+        in_s16x4     = vld1_lane_s16( &in[ 2 * k + 1 ], in_s16x4, 1 );                                  /* in{0,1} = in[ 2 * k + {0,1} ];     */
+        in_s32x4     = vshll_n_s16( in_s16x4, 15 );                                                     /* in{0,1} << 15                      */
+        t_s32x2      = vqdmulh_lane_s32( vget_low_s32( in_s32x4 ), B_Q28_s32x2, 0 );                    /* silk_SMULWB( B_Q28[ 0 ], in{0,1} ) */
+        in_s32x4     = vcombine_s32( vget_low_s32( in_s32x4 ), vget_low_s32( in_s32x4 ) );              /* in{0,1,0,1} << 15                  */
+        silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, t_s32x2, in_s32x4, &S_s32x4, &out32_Q14_s32x2 );
+
+        /* Scale back to Q0 and saturate */
+        out32_Q14_s32x2 = vadd_s32( out32_Q14_s32x2, offset_s32x2 );                                    /* out32_Q14_{0,1} + (1<<14) - 1                                                              */
+        out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2, out32_Q14_s32x2 );                             /* out32_Q14_{0,1,0,1} + (1<<14) - 1                                                          */
+        out_s16x4       = vqshrn_n_s32( out32_Q14_s32x4, 14 );                                          /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,0,1} + (1<<14) - 1, 14 ) )             */
+        vst1_lane_s16( &out[ 2 * k + 0 ], out_s16x4, 0 );                                               /* out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_0 + (1<<14) - 1, 14 ) ); */
+        vst1_lane_s16( &out[ 2 * k + 1 ], out_s16x4, 1 );                                               /* out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_1 + (1<<14) - 1, 14 ) ); */
+    }
+
+    vst1q_lane_s32( &S[ 0 ], S_s32x4, 0 );                                                              /* S[ 0 ] = S0; */
+    vst1q_lane_s32( &S[ 1 ], S_s32x4, 2 );                                                              /* S[ 1 ] = S2; */
+    vst1q_lane_s32( &S[ 2 ], S_s32x4, 1 );                                                              /* S[ 2 ] = S1; */
+    vst1q_lane_s32( &S[ 3 ], S_s32x4, 3 );                                                              /* S[ 3 ] = S3; */
+
+#ifdef OPUS_CHECK_ASM
+    silk_assert( !memcmp( S_c, S, sizeof( S_c ) ) );
+    silk_assert( !memcmp( out_c, out, 2 * len * sizeof( opus_int16 ) ) );
+    RESTORE_STACK;
+#endif
+}
diff --git a/silk/arm/macros_armv4.h b/silk/arm/macros_armv4.h
index 3f30e97..877eb18 100644
--- a/silk/arm/macros_armv4.h
+++ b/silk/arm/macros_armv4.h
@@ -28,6 +28,11 @@
 #ifndef SILK_MACROS_ARMv4_H
 #define SILK_MACROS_ARMv4_H
 
+/* This macro only avoids the undefined behaviour from a left shift of
+   a negative value. It should only be used in macros that can't include
+   SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
+#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
+
 /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
 #undef silk_SMULWB
 static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
@@ -38,7 +43,7 @@
       "#silk_SMULWB\n\t"
       "smull %0, %1, %2, %3\n\t"
       : "=&r"(rd_lo), "=&r"(rd_hi)
-      : "%r"(a), "r"(b<<16)
+      : "%r"(a), "r"(SAFE_SHL(b,16))
   );
   return rd_hi;
 }
@@ -80,7 +85,7 @@
     : "=&r"(rd_lo), "=&r"(rd_hi)
     : "%r"(a), "r"(b)
   );
-  return (rd_hi<<16)+(rd_lo>>16);
+  return SAFE_SHL(rd_hi,16)+(rd_lo>>16);
 }
 #define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b))
 
@@ -96,8 +101,10 @@
     : "=&r"(rd_lo), "=&r"(rd_hi)
     : "%r"(b), "r"(c)
   );
-  return a+(rd_hi<<16)+(rd_lo>>16);
+  return a+SAFE_SHL(rd_hi,16)+(rd_lo>>16);
 }
 #define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c))
 
+#undef SAFE_SHL
+
 #endif /* SILK_MACROS_ARMv4_H */
diff --git a/silk/arm/macros_armv5e.h b/silk/arm/macros_armv5e.h
index aad4117e..b14ec65 100644
--- a/silk/arm/macros_armv5e.h
+++ b/silk/arm/macros_armv5e.h
@@ -29,6 +29,11 @@
 #ifndef SILK_MACROS_ARMv5E_H
 #define SILK_MACROS_ARMv5E_H
 
+/* This macro only avoids the undefined behaviour from a left shift of
+   a negative value. It should only be used in macros that can't include
+   SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
+#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
+
 /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
 #undef silk_SMULWB
 static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)
@@ -190,7 +195,7 @@
       "#silk_CLZ16\n\t"
       "clz %0, %1;\n"
       : "=r"(res)
-      : "r"(in16<<16|0x8000)
+      : "r"(SAFE_SHL(in16,16)|0x8000)
   );
   return res;
 }
@@ -210,4 +215,6 @@
 }
 #define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))
 
+#undef SAFE_SHL
+
 #endif /* SILK_MACROS_ARMv5E_H */
diff --git a/silk/biquad_alt.c b/silk/biquad_alt.c
index d55f5ee..54566a4 100644
--- a/silk/biquad_alt.c
+++ b/silk/biquad_alt.c
@@ -39,14 +39,13 @@
 #include "SigProc_FIX.h"
 
 /* Second order ARMA filter, alternative implementation */
-void silk_biquad_alt(
+void silk_biquad_alt_stride1(
     const opus_int16            *in,                /* I     input signal                                               */
     const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
     const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
     opus_int32                  *S,                 /* I/O   State vector [2]                                           */
     opus_int16                  *out,               /* O     output signal                                              */
-    const opus_int32            len,                /* I     signal length (must be even)                               */
-    opus_int                    stride              /* I     Operate on interleaved signal if > 1                       */
+    const opus_int32            len                 /* I     signal length (must be even)                               */
 )
 {
     /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
@@ -61,7 +60,7 @@
 
     for( k = 0; k < len; k++ ) {
         /* S[ 0 ], S[ 1 ]: Q12 */
-        inval = in[ k * stride ];
+        inval = in[ k ];
         out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
 
         S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
@@ -73,6 +72,50 @@
         S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
 
         /* Scale back to Q0 and saturate */
-        out[ k * stride ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
+        out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
+    }
+}
+
+void silk_biquad_alt_stride2_c(
+    const opus_int16            *in,                /* I     input signal                                               */
+    const opus_int32            *B_Q28,             /* I     MA coefficients [3]                                        */
+    const opus_int32            *A_Q28,             /* I     AR coefficients [2]                                        */
+    opus_int32                  *S,                 /* I/O   State vector [4]                                           */
+    opus_int16                  *out,               /* O     output signal                                              */
+    const opus_int32            len                 /* I     signal length (must be even)                               */
+)
+{
+    /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
+    opus_int   k;
+    opus_int32 A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14[ 2 ];
+
+    /* Negate A_Q28 values and split in two parts */
+    A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF;        /* lower part */
+    A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 );      /* upper part */
+    A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF;        /* lower part */
+    A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 );      /* upper part */
+
+    for( k = 0; k < len; k++ ) {
+        /* S[ 0 ], S[ 1 ], S[ 2 ], S[ 3 ]: Q12 */
+        out32_Q14[ 0 ] = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], in[ 2 * k + 0 ] ), 2 );
+        out32_Q14[ 1 ] = silk_LSHIFT( silk_SMLAWB( S[ 2 ], B_Q28[ 0 ], in[ 2 * k + 1 ] ), 2 );
+
+        S[ 0 ] = S[ 1 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A0_L_Q28 ), 14 );
+        S[ 2 ] = S[ 3 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A0_L_Q28 ), 14 );
+        S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14[ 0 ], A0_U_Q28 );
+        S[ 2 ] = silk_SMLAWB( S[ 2 ], out32_Q14[ 1 ], A0_U_Q28 );
+        S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], in[ 2 * k + 0 ] );
+        S[ 2 ] = silk_SMLAWB( S[ 2 ], B_Q28[ 1 ], in[ 2 * k + 1 ] );
+
+        S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A1_L_Q28 ), 14 );
+        S[ 3 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A1_L_Q28 ), 14 );
+        S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14[ 0 ], A1_U_Q28 );
+        S[ 3 ] = silk_SMLAWB( S[ 3 ], out32_Q14[ 1 ], A1_U_Q28 );
+        S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], in[ 2 * k + 0 ] );
+        S[ 3 ] = silk_SMLAWB( S[ 3 ], B_Q28[ 2 ], in[ 2 * k + 1 ] );
+
+        /* Scale back to Q0 and saturate */
+        out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 0 ] + (1<<14) - 1, 14 ) );
+        out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 1 ] + (1<<14) - 1, 14 ) );
     }
 }
diff --git a/silk/bwexpander.c b/silk/bwexpander.c
index 2eb4456..afa9790 100644
--- a/silk/bwexpander.c
+++ b/silk/bwexpander.c
@@ -45,7 +45,7 @@
     /* Bias in silk_SMULWB can lead to unstable filters                                */
     for( i = 0; i < d - 1; i++ ) {
         ar[ i ]    = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ]             ), 16 );
-        chirp_Q16 +=            silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
+        chirp_Q16 +=             silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
     }
     ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
 }
diff --git a/silk/control.h b/silk/control.h
index 747e542..b76ec33 100644
--- a/silk/control.h
+++ b/silk/control.h
@@ -77,6 +77,9 @@
     /* I:   Flag to enable in-band Forward Error Correction (FEC); 0/1                      */
     opus_int useInBandFEC;
 
+    /* I:   Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */
+    opus_int LBRR_coded;
+
     /* I:   Flag to enable discontinuous transmission (DTX); 0/1                            */
     opus_int useDTX;
 
@@ -110,6 +113,11 @@
     /* O:   Tells the Opus encoder we're ready to switch                                    */
     opus_int switchReady;
 
+    /* O: SILK Signal type */
+    opus_int signalType;
+
+    /* O: SILK offset (dithering) */
+    opus_int offset;
 } silk_EncControlStruct;
 
 /**************************************************************************/
diff --git a/silk/control_SNR.c b/silk/control_SNR.c
index cee87eb..464c1ac 100644
--- a/silk/control_SNR.c
+++ b/silk/control_SNR.c
@@ -64,8 +64,7 @@
         /* Find bitrate interval in table and interpolate */
         for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
             if( TargetRate_bps <= rateTable[ k ] ) {
-                frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ),
-                                                 rateTable[ k ] - rateTable[ k - 1 ] );
+                frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), rateTable[ k ] - rateTable[ k - 1 ] );
                 psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] );
                 break;
             }
diff --git a/silk/control_codec.c b/silk/control_codec.c
index 044eea3..9350fd4 100644
--- a/silk/control_codec.c
+++ b/silk/control_codec.c
@@ -57,7 +57,7 @@
 
 static OPUS_INLINE opus_int silk_setup_LBRR(
     silk_encoder_state              *psEncC,            /* I/O                      */
-    const opus_int32                TargetRate_bps      /* I                        */
+    const silk_EncControlStruct     *encControl         /* I                        */
 );
 
 
@@ -65,7 +65,6 @@
 opus_int silk_control_encoder(
     silk_encoder_state_Fxx          *psEnc,                                 /* I/O  Pointer to Silk encoder state                                               */
     silk_EncControlStruct           *encControl,                            /* I    Control structure                                                           */
-    const opus_int32                TargetRate_bps,                         /* I    Target max bitrate (bps)                                                    */
     const opus_int                  allow_bw_switch,                        /* I    Flag to allow switching audio bandwidth                                     */
     const opus_int                  channelNb,                              /* I    Channel number                                                              */
     const opus_int                  force_fs_kHz
@@ -125,7 +124,7 @@
     /********************************************/
     /* Set LBRR usage                           */
     /********************************************/
-    ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps );
+    ret += silk_setup_LBRR( &psEnc->sCmn, encControl );
 
     psEnc->sCmn.controlled_since_last_payload = 1;
 
@@ -244,7 +243,6 @@
     if( psEnc->sCmn.fs_kHz != fs_kHz ) {
         /* reset part of the state */
         silk_memset( &psEnc->sShape,               0, sizeof( psEnc->sShape ) );
-        silk_memset( &psEnc->sPrefilt,             0, sizeof( psEnc->sPrefilt ) );
         silk_memset( &psEnc->sCmn.sNSQ,            0, sizeof( psEnc->sCmn.sNSQ ) );
         silk_memset( psEnc->sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
         silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );
@@ -255,7 +253,6 @@
         /* Initialize non-zero parameters */
         psEnc->sCmn.prevLag                     = 100;
         psEnc->sCmn.first_frame_after_reset     = 1;
-        psEnc->sPrefilt.lagPrev                 = 100;
         psEnc->sShape.LastGainIndex             = 10;
         psEnc->sCmn.sNSQ.lagPrev                = 100;
         psEnc->sCmn.sNSQ.prev_gain_Q16          = 65536;
@@ -293,13 +290,10 @@
             psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
         }
         if( psEnc->sCmn.fs_kHz == 16 ) {
-            psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 );
             psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
         } else if( psEnc->sCmn.fs_kHz == 12 ) {
-            psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 );
             psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
         } else {
-            psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 );
             psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
         }
     }
@@ -319,60 +313,75 @@
 
     /* Set encoding complexity */
     silk_assert( Complexity >= 0 && Complexity <= 10 );
-    if( Complexity < 2 ) {
+    if( Complexity < 1 ) {
         psEncC->pitchEstimationComplexity       = SILK_PE_MIN_COMPLEX;
         psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.8, 16 );
         psEncC->pitchEstimationLPCOrder         = 6;
-        psEncC->shapingLPCOrder                 = 8;
+        psEncC->shapingLPCOrder                 = 12;
         psEncC->la_shape                        = 3 * psEncC->fs_kHz;
         psEncC->nStatesDelayedDecision          = 1;
         psEncC->useInterpolatedNLSFs            = 0;
-        psEncC->LTPQuantLowComplexity           = 1;
+        psEncC->NLSF_MSVQ_Survivors             = 2;
+        psEncC->warping_Q16                     = 0;
+    } else if( Complexity < 2 ) {
+        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
+        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.76, 16 );
+        psEncC->pitchEstimationLPCOrder         = 8;
+        psEncC->shapingLPCOrder                 = 14;
+        psEncC->la_shape                        = 5 * psEncC->fs_kHz;
+        psEncC->nStatesDelayedDecision          = 1;
+        psEncC->useInterpolatedNLSFs            = 0;
+        psEncC->NLSF_MSVQ_Survivors             = 3;
+        psEncC->warping_Q16                     = 0;
+    } else if( Complexity < 3 ) {
+        psEncC->pitchEstimationComplexity       = SILK_PE_MIN_COMPLEX;
+        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.8, 16 );
+        psEncC->pitchEstimationLPCOrder         = 6;
+        psEncC->shapingLPCOrder                 = 12;
+        psEncC->la_shape                        = 3 * psEncC->fs_kHz;
+        psEncC->nStatesDelayedDecision          = 2;
+        psEncC->useInterpolatedNLSFs            = 0;
         psEncC->NLSF_MSVQ_Survivors             = 2;
         psEncC->warping_Q16                     = 0;
     } else if( Complexity < 4 ) {
         psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
         psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.76, 16 );
         psEncC->pitchEstimationLPCOrder         = 8;
-        psEncC->shapingLPCOrder                 = 10;
+        psEncC->shapingLPCOrder                 = 14;
         psEncC->la_shape                        = 5 * psEncC->fs_kHz;
-        psEncC->nStatesDelayedDecision          = 1;
+        psEncC->nStatesDelayedDecision          = 2;
         psEncC->useInterpolatedNLSFs            = 0;
-        psEncC->LTPQuantLowComplexity           = 0;
         psEncC->NLSF_MSVQ_Survivors             = 4;
         psEncC->warping_Q16                     = 0;
     } else if( Complexity < 6 ) {
         psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
         psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.74, 16 );
         psEncC->pitchEstimationLPCOrder         = 10;
-        psEncC->shapingLPCOrder                 = 12;
+        psEncC->shapingLPCOrder                 = 16;
         psEncC->la_shape                        = 5 * psEncC->fs_kHz;
         psEncC->nStatesDelayedDecision          = 2;
         psEncC->useInterpolatedNLSFs            = 1;
-        psEncC->LTPQuantLowComplexity           = 0;
-        psEncC->NLSF_MSVQ_Survivors             = 8;
+        psEncC->NLSF_MSVQ_Survivors             = 6;
         psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
     } else if( Complexity < 8 ) {
         psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
         psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.72, 16 );
         psEncC->pitchEstimationLPCOrder         = 12;
-        psEncC->shapingLPCOrder                 = 14;
+        psEncC->shapingLPCOrder                 = 20;
         psEncC->la_shape                        = 5 * psEncC->fs_kHz;
         psEncC->nStatesDelayedDecision          = 3;
         psEncC->useInterpolatedNLSFs            = 1;
-        psEncC->LTPQuantLowComplexity           = 0;
-        psEncC->NLSF_MSVQ_Survivors             = 16;
+        psEncC->NLSF_MSVQ_Survivors             = 8;
         psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
     } else {
         psEncC->pitchEstimationComplexity       = SILK_PE_MAX_COMPLEX;
         psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.7, 16 );
         psEncC->pitchEstimationLPCOrder         = 16;
-        psEncC->shapingLPCOrder                 = 16;
+        psEncC->shapingLPCOrder                 = 24;
         psEncC->la_shape                        = 5 * psEncC->fs_kHz;
         psEncC->nStatesDelayedDecision          = MAX_DEL_DEC_STATES;
         psEncC->useInterpolatedNLSFs            = 1;
-        psEncC->LTPQuantLowComplexity           = 0;
-        psEncC->NLSF_MSVQ_Survivors             = 32;
+        psEncC->NLSF_MSVQ_Survivors             = 16;
         psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
     }
 
@@ -387,40 +396,26 @@
     silk_assert( psEncC->warping_Q16             <= 32767                    );
     silk_assert( psEncC->la_shape                <= LA_SHAPE_MAX             );
     silk_assert( psEncC->shapeWinLength          <= SHAPE_LPC_WIN_MAX        );
-    silk_assert( psEncC->NLSF_MSVQ_Survivors     <= NLSF_VQ_MAX_SURVIVORS    );
 
     return ret;
 }
 
 static OPUS_INLINE opus_int silk_setup_LBRR(
     silk_encoder_state          *psEncC,            /* I/O                      */
-    const opus_int32            TargetRate_bps      /* I                        */
+    const silk_EncControlStruct *encControl         /* I                        */
 )
 {
     opus_int   LBRR_in_previous_packet, ret = SILK_NO_ERROR;
-    opus_int32 LBRR_rate_thres_bps;
 
     LBRR_in_previous_packet = psEncC->LBRR_enabled;
-    psEncC->LBRR_enabled = 0;
-    if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) {
-        if( psEncC->fs_kHz == 8 ) {
-            LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS;
-        } else if( psEncC->fs_kHz == 12 ) {
-            LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS;
+    psEncC->LBRR_enabled = encControl->LBRR_coded;
+    if( psEncC->LBRR_enabled ) {
+        /* Set gain increase for coding LBRR excitation */
+        if( LBRR_in_previous_packet == 0 ) {
+            /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
+            psEncC->LBRR_GainIncreases = 7;
         } else {
-            LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS;
-        }
-        LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
-
-        if( TargetRate_bps > LBRR_rate_thres_bps ) {
-            /* Set gain increase for coding LBRR excitation */
-            if( LBRR_in_previous_packet == 0 ) {
-                /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
-                psEncC->LBRR_GainIncreases = 7;
-            } else {
-                psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
-            }
-            psEncC->LBRR_enabled = 1;
+            psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
         }
     }
 
diff --git a/silk/debug.h b/silk/debug.h
index efb6d3e..6f68c1c 100644
--- a/silk/debug.h
+++ b/silk/debug.h
@@ -39,23 +39,10 @@
 
 unsigned long GetHighResolutionTime(void); /* O  time in usec*/
 
-/* make SILK_DEBUG dependent on compiler's _DEBUG */
-#if defined _WIN32
-    #ifdef _DEBUG
-        #define SILK_DEBUG  1
-    #else
-        #define SILK_DEBUG  0
-    #endif
-
-    /* overrule the above */
-    #if 0
-    /*  #define NO_ASSERTS*/
-    #undef  SILK_DEBUG
-    #define SILK_DEBUG  1
-    #endif
-#else
-    #define SILK_DEBUG  0
-#endif
+/* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping
+ * intermediate signals from the codec.
+ */
+#define SILK_DEBUG 0
 
 /* Flag for using timers */
 #define SILK_TIC_TOC    0
diff --git a/silk/decode_core.c b/silk/decode_core.c
index e569c0e..fd4e857 100644
--- a/silk/decode_core.c
+++ b/silk/decode_core.c
@@ -225,8 +225,6 @@
             pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
         }
 
-        /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */
-
         /* Update LPC filter state */
         silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
         pexc_Q14 += psDec->subfr_length;
diff --git a/silk/decode_frame.c b/silk/decode_frame.c
index a605d95..dfa73c4 100644
--- a/silk/decode_frame.c
+++ b/silk/decode_frame.c
@@ -97,6 +97,7 @@
         psDec->first_frame_after_reset = 0;
     } else {
         /* Handle packet loss by extrapolation */
+        psDec->indices.signalType = psDec->prevSignalType;
         silk_PLC( psDec, psDecCtrl, pOut, 1, arch );
     }
 
diff --git a/silk/decode_parameters.c b/silk/decode_parameters.c
index e345b1d..a56a409 100644
--- a/silk/decode_parameters.c
+++ b/silk/decode_parameters.c
@@ -52,7 +52,7 @@
     silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
 
     /* Convert NLSF parameters to AR prediction filter coefficients */
-    silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
+    silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order, psDec->arch );
 
     /* If just reset, e.g., because internal Fs changed, do not allow interpolation */
     /* improves the case of packet loss in the first frame after a switch           */
@@ -69,7 +69,7 @@
         }
 
         /* Convert NLSF parameters to AR prediction filter coefficients */
-        silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
+        silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order, psDec->arch );
     } else {
         /* Copy LPC coefficients for first half from second half */
         silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
diff --git a/silk/define.h b/silk/define.h
index 19c9b00..1286048 100644
--- a/silk/define.h
+++ b/silk/define.h
@@ -56,6 +56,7 @@
 /* DTX settings */
 #define NB_SPEECH_FRAMES_BEFORE_DTX             10      /* eq 200 ms */
 #define MAX_CONSECUTIVE_DTX                     20      /* eq 400 ms */
+#define DTX_ACTIVITY_THRESHOLD                  0.1f
 
 /* Maximum sampling frequency */
 #define MAX_FS_KHZ                              16
@@ -147,7 +148,7 @@
 #define USE_HARM_SHAPING                        1
 
 /* Max LPC order of noise shaping filters */
-#define MAX_SHAPE_LPC_ORDER                     16
+#define MAX_SHAPE_LPC_ORDER                     24
 
 #define HARM_SHAPE_FIR_TAPS                     3
 
@@ -157,8 +158,7 @@
 #define LTP_BUF_LENGTH                          512
 #define LTP_MASK                                ( LTP_BUF_LENGTH - 1 )
 
-#define DECISION_DELAY                          32
-#define DECISION_DELAY_MASK                     ( DECISION_DELAY - 1 )
+#define DECISION_DELAY                          40
 
 /* Number of subframes for excitation entropy coding */
 #define SHELL_CODEC_FRAME_LENGTH                16
@@ -173,11 +173,7 @@
 
 #define MAX_MATRIX_SIZE                         MAX_LPC_ORDER /* Max of LPC Order and LTP order */
 
-#if( MAX_LPC_ORDER > DECISION_DELAY )
 # define NSQ_LPC_BUF_LENGTH                     MAX_LPC_ORDER
-#else
-# define NSQ_LPC_BUF_LENGTH                     DECISION_DELAY
-#endif
 
 /***************************/
 /* Voice activity detector */
@@ -205,7 +201,6 @@
 /******************/
 #define NLSF_W_Q                                2
 #define NLSF_VQ_MAX_VECTORS                     32
-#define NLSF_VQ_MAX_SURVIVORS                   32
 #define NLSF_QUANT_MAX_AMPLITUDE                4
 #define NLSF_QUANT_MAX_AMPLITUDE_EXT            10
 #define NLSF_QUANT_LEVEL_ADJ                    0.1
diff --git a/silk/enc_API.c b/silk/enc_API.c
index f806028..701c290 100644
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -233,11 +233,10 @@
         }
     }
 
-    TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 );
     for( n = 0; n < encControl->nChannelsInternal; n++ ) {
         /* Force the side channel to the same rate as the mid */
         opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
-        if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
+        if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
             silk_assert( 0 );
             RESTORE_STACK;
             return ret;
@@ -416,7 +415,6 @@
                     /* Reset side channel encoder memory for first frame with side coding */
                     if( psEnc->prev_decode_only_middle == 1 ) {
                         silk_memset( &psEnc->state_Fxx[ 1 ].sShape,               0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
-                        silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt,             0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) );
                         silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ,            0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
                         silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15,   0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
                         silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
@@ -557,6 +555,10 @@
         }
     }
 
+    encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType;
+    encControl->offset = silk_Quantization_Offsets_Q10
+                         [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ]
+                         [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ];
     RESTORE_STACK;
     return ret;
 }
diff --git a/silk/fixed/arm/warped_autocorrelation_FIX_arm.h b/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
new file mode 100644
index 0000000..1992e43
--- /dev/null
+++ b/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
@@ -0,0 +1,68 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc.
+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 SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
+# define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
+
+# include "celt/arm/armcpu.h"
+
+# if defined(FIXED_POINT)
+
+#  if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+void silk_warped_autocorrelation_FIX_neon(
+          opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */
+          opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */
+    const opus_int16                *input,                                 /* I    Input data to correlate                                                     */
+    const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */
+    const opus_int                  length,                                 /* I    Length of input                                                             */
+    const opus_int                  order                                   /* I    Correlation order (even)                                                    */
+);
+
+#  if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
+#   define OVERRIDE_silk_warped_autocorrelation_FIX (1)
+#   define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
+    ((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order))
+#  endif
+#  endif
+
+#  if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
+/*Is run-time CPU detection enabled on this platform?*/
+#   if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK+1])(opus_int32*, opus_int*, const opus_int16*, const opus_int, const opus_int, const opus_int);
+#    define OVERRIDE_silk_warped_autocorrelation_FIX (1)
+#    define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
+    ((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order))
+#   elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+#    define OVERRIDE_silk_warped_autocorrelation_FIX (1)
+#    define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
+    ((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order))
+#   endif
+#  endif
+
+# endif /* end FIXED_POINT */
+
+#endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */
diff --git a/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c b/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
new file mode 100644
index 0000000..00a70cb
--- /dev/null
+++ b/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
@@ -0,0 +1,260 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc., 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.
+- 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <arm_neon.h>
+#ifdef OPUS_CHECK_ASM
+# include <string.h>
+#endif
+#include "stack_alloc.h"
+#include "main_FIX.h"
+
+static OPUS_INLINE void calc_corr( const opus_int32 *const input_QS, opus_int64 *const corr_QC, const opus_int offset, const int32x4_t state_QS_s32x4 )
+{
+    int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ];
+    const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset );
+    corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 );
+    corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 );
+    t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) );
+    t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) );
+    corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC );
+    corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC );
+    vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] );
+    vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] );
+}
+
+static OPUS_INLINE int32x4_t calc_state( const int32x4_t state_QS0_s32x4, const int32x4_t state_QS0_1_s32x4, const int32x4_t state_QS1_1_s32x4, const int32x4_t warping_Q16_s32x4 )
+{
+    int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 );
+    t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 );
+    return vaddq_s32( state_QS1_1_s32x4, t_s32x4 );
+}
+
+void silk_warped_autocorrelation_FIX_neon(
+          opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */
+          opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */
+    const opus_int16                *input,                                 /* I    Input data to correlate                                                     */
+    const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */
+    const opus_int                  length,                                 /* I    Length of input                                                             */
+    const opus_int                  order                                   /* I    Correlation order (even)                                                    */
+)
+{
+    if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) {
+        silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order );
+    } else {
+        opus_int       n, i, lsh;
+        opus_int64     corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */
+        opus_int64     corr_QC_orderT;
+        int64x2_t      lsh_s64x2;
+        const opus_int orderT = ( order + 3 ) & ~3;
+        opus_int64     *corr_QCT;
+        opus_int32     *input_QS;
+        VARDECL( opus_int32, input_QST );
+        VARDECL( opus_int32, state );
+        SAVE_STACK;
+
+        /* Order must be even */
+        silk_assert( ( order & 1 ) == 0 );
+        silk_assert( 2 * QS - QC >= 0 );
+
+        ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 );
+
+        input_QS = input_QST;
+        /* input_QS has zero paddings in the beginning and end. */
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+
+        /* Loop over samples */
+        for( n = 0; n < length - 7; n += 8, input_QS += 8 ) {
+            const int16x8_t t0_s16x4 = vld1q_s16( input + n );
+            vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) );
+            vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) );
+        }
+        for( ; n < length; n++, input_QS++ ) {
+            input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS );
+        }
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS += 4;
+        vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
+        input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT;
+
+        /* The following loop runs ( length + order ) times, with ( order ) extra epilogues.                  */
+        /* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues.       */
+        /* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */
+
+        /* Keep the C code here to help understand the intrinsics optimization. */
+        /*
+        {
+            opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
+            opus_int32 *state_QST[ 3 ];
+            state_QST[ 0 ] = state_QS[ 0 ];
+            state_QST[ 1 ] = state_QS[ 1 ];
+            for( n = 0; n < length + order; n++, input_QS++ ) {
+                state_QST[ 0 ][ orderT ] = input_QS[ orderT ];
+                for( i = 0; i < orderT; i++ ) {
+                    corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC );
+                    state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 );
+                }
+                state_QST[ 2 ] = state_QST[ 0 ];
+                state_QST[ 0 ] = state_QST[ 1 ];
+                state_QST[ 1 ] = state_QST[ 2 ];
+            }
+        }
+        */
+
+        {
+            const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 );
+            const opus_int32 *in = input_QS + orderT;
+            opus_int o = orderT;
+            int32x4_t state_QS_s32x4[ 3 ][ 2 ];
+
+            ALLOC( state, length + orderT, opus_int32 );
+            state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 );
+
+            /* Calculate 8 taps of all inputs in each loop. */
+            do {
+                state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] =
+                state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 );
+                n = 0;
+                do {
+                    calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] );
+                    calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] );
+                    state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n );
+                    vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 );
+                    state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 );
+                    state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 );
+                    state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 );
+                    state_QS_s32x4[ 0 ][ 1 ] = calc_state( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], state_QS_s32x4[ 1 ][ 1 ], warping_Q16_s32x4 );
+                    state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
+                    state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ];
+                } while( ++n < ( length + order ) );
+                in = state;
+                o -= 8;
+            } while( o > 4 );
+
+            if( o ) {
+                /* Calculate the last 4 taps of all inputs. */
+                opus_int32 *stateT = state;
+                silk_assert( o == 4 );
+                state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 );
+                n = length + order;
+                do {
+                    calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] );
+                    state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT );
+                    vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 );
+                    state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 );
+                    state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 );
+                    state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
+                    input_QS++;
+                    stateT++;
+                } while( --n );
+            }
+        }
+
+        {
+            const opus_int16 *inputT = input;
+            int32x4_t t_s32x4;
+            int64x1_t t_s64x1;
+            int64x2_t t_s64x2 = vdupq_n_s64( 0 );
+            for( n = 0; n <= length - 8; n += 8 ) {
+                int16x8_t input_s16x8 = vld1q_s16( inputT );
+                t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) );
+                t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) );
+                t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) );
+                t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) );
+                inputT += 8;
+            }
+            t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) );
+            corr_QC_orderT = vget_lane_s64( t_s64x1, 0 );
+            for( ; n < length; n++ ) {
+                corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] );
+            }
+            corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC );
+            corr_QC[ orderT ] = corr_QC_orderT;
+        }
+
+        corr_QCT = corr_QC + orderT - order;
+        lsh = silk_CLZ64( corr_QC_orderT ) - 35;
+        lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
+        *scale = -( QC + lsh );
+        silk_assert( *scale >= -30 && *scale <= 12 );
+        lsh_s64x2 = vdupq_n_s64( lsh );
+        for( i = 0; i <= order - 3; i += 4 ) {
+            int32x4_t corr_s32x4;
+            int64x2_t corr_QC0_s64x2, corr_QC1_s64x2;
+            corr_QC0_s64x2 = vld1q_s64( corr_QCT + i );
+            corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 );
+            corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 );
+            corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 );
+            corr_s32x4     = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) );
+            corr_s32x4     = vrev64q_s32( corr_s32x4 );
+            vst1q_s32( corr + order - i - 3, corr_s32x4 );
+        }
+        if( lsh >= 0 ) {
+            for( ; i < order + 1; i++ ) {
+                corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) );
+            }
+        } else {
+            for( ; i < order + 1; i++ ) {
+                corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) );
+            }
+        }
+        silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/
+        RESTORE_STACK;
+    }
+
+#ifdef OPUS_CHECK_ASM
+    {
+        opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ];
+        opus_int   scale_c;
+        silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order );
+        silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) );
+        silk_assert( scale_c == *scale );
+    }
+#endif
+}
diff --git a/silk/fixed/burg_modified_FIX.c b/silk/fixed/burg_modified_FIX.c
index 17d0e09..80edbdf 100644
--- a/silk/fixed/burg_modified_FIX.c
+++ b/silk/fixed/burg_modified_FIX.c
@@ -37,7 +37,7 @@
 #define MAX_FRAME_SIZE              384             /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
 
 #define QA                          25
-#define N_BITS_HEAD_ROOM            2
+#define N_BITS_HEAD_ROOM            3
 #define MIN_RSHIFTS                 -16
 #define MAX_RSHIFTS                 (32 - QA)
 
diff --git a/silk/fixed/corrMatrix_FIX.c b/silk/fixed/corrMatrix_FIX.c
index c1d437c..1b4a29c 100644
--- a/silk/fixed/corrMatrix_FIX.c
+++ b/silk/fixed/corrMatrix_FIX.c
@@ -58,7 +58,7 @@
         for( lag = 0; lag < order; lag++ ) {
             inner_prod = 0;
             for( i = 0; i < L; i++ ) {
-                inner_prod += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
+                inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
             }
             Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
             ptr1--; /* Go to next column of X */
@@ -77,61 +77,54 @@
     const opus_int16                *x,                                     /* I    x vector [L + order - 1] used to form data matrix X                         */
     const opus_int                  L,                                      /* I    Length of vectors                                                           */
     const opus_int                  order,                                  /* I    Max lag for correlation                                                     */
-    const opus_int                  head_room,                              /* I    Desired headroom                                                            */
     opus_int32                      *XX,                                    /* O    Pointer to X'*X correlation matrix [ order x order ]                        */
-    opus_int                        *rshifts,                               /* I/O  Right shifts of correlations                                                */
+    opus_int32                      *nrg,                                    /* O    Energy of x vector                                                            */
+    opus_int                        *rshifts,                               /* O    Right shifts of correlations and energy                                     */
     int                             arch                                    /* I    Run-time architecture                                                       */
 )
 {
-    opus_int         i, j, lag, rshifts_local, head_room_rshifts;
+    opus_int         i, j, lag;
     opus_int32       energy;
     const opus_int16 *ptr1, *ptr2;
 
     /* Calculate energy to find shift used to fit in 32 bits */
-    silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );
-    /* Add shifts to get the desired head room */
-    head_room_rshifts = silk_max( head_room - silk_CLZ32( energy ), 0 );
-
-    energy = silk_RSHIFT32( energy, head_room_rshifts );
-    rshifts_local += head_room_rshifts;
+    silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 );
+    energy = *nrg;
 
     /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
     /* Remove contribution of first order - 1 samples */
     for( i = 0; i < order - 1; i++ ) {
-        energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), rshifts_local );
-    }
-    if( rshifts_local < *rshifts ) {
-        /* Adjust energy */
-        energy = silk_RSHIFT32( energy, *rshifts - rshifts_local );
-        rshifts_local = *rshifts;
+        energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts );
     }
 
     /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
     /* Fill out the diagonal of the correlation matrix */
     matrix_ptr( XX, 0, 0, order ) = energy;
+    silk_assert( energy >= 0 );
     ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
     for( j = 1; j < order; j++ ) {
-        energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );
-        energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );
+        energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) );
+        energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) );
         matrix_ptr( XX, j, j, order ) = energy;
+        silk_assert( energy >= 0 );
     }
 
     ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
     /* Calculate the remaining elements of the correlation matrix */
-    if( rshifts_local > 0 ) {
+    if( *rshifts > 0 ) {
         /* Right shifting used */
         for( lag = 1; lag < order; lag++ ) {
             /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
             energy = 0;
             for( i = 0; i < L; i++ ) {
-                energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );
+                energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts );
             }
             /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
             matrix_ptr( XX, lag, 0, order ) = energy;
             matrix_ptr( XX, 0, lag, order ) = energy;
             for( j = 1; j < ( order - lag ); j++ ) {
-                energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );
-                energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );
+                energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) );
+                energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) );
                 matrix_ptr( XX, lag + j, j, order ) = energy;
                 matrix_ptr( XX, j, lag + j, order ) = energy;
             }
@@ -153,6 +146,5 @@
             ptr2--;/* Update pointer to first sample of next column (lag) in X */
         }
     }
-    *rshifts = rshifts_local;
 }
 
diff --git a/silk/fixed/encode_frame_FIX.c b/silk/fixed/encode_frame_FIX.c
index 5ef44b0..4f9e086 100644
--- a/silk/fixed/encode_frame_FIX.c
+++ b/silk/fixed/encode_frame_FIX.c
@@ -29,6 +29,7 @@
 #include "config.h"
 #endif
 
+#include <stdlib.h>
 #include "main_FIX.h"
 #include "stack_alloc.h"
 #include "tuning_parameters.h"
@@ -37,7 +38,7 @@
 static OPUS_INLINE void silk_LBRR_encode_FIX(
     silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
     silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */
-    const opus_int32                xfw_Q3[],                               /* I    Input signal                                                                */
+    const opus_int16                x16[],                                  /* I    Input signal                                                                */
     opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */
 );
 
@@ -94,6 +95,9 @@
     opus_int16   ec_prevLagIndex_copy;
     opus_int     ec_prevSignalType_copy;
     opus_int8    LastGainIndex_copy2;
+    opus_int     gain_lock[ MAX_NB_SUBFR ] = {0};
+    opus_int16   best_gain_mult[ MAX_NB_SUBFR ];
+    opus_int     best_sum[ MAX_NB_SUBFR ];
     SAVE_STACK;
 
     /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
@@ -118,7 +122,6 @@
     silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
 
     if( !psEnc->sCmn.prefillFlag ) {
-        VARDECL( opus_int32, xfw_Q3 );
         VARDECL( opus_int16, res_pitch );
         VARDECL( opus_uint8, ec_buf_copy );
         opus_int16 *res_pitch_frame;
@@ -132,7 +135,7 @@
         /*****************************************/
         /* Find pitch lags, initial LPC analysis */
         /*****************************************/
-        silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
+        silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
 
         /************************/
         /* Noise shape analysis */
@@ -142,23 +145,17 @@
         /***************************************************/
         /* Find linear prediction coefficients (LPC + LTP) */
         /***************************************************/
-        silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
+        silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
 
         /****************************************/
         /* Process gains                        */
         /****************************************/
         silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
 
-        /*****************************************/
-        /* Prefiltering for noise shaper         */
-        /*****************************************/
-        ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 );
-        silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame );
-
         /****************************************/
         /* Low Bitrate Redundant Encoding       */
         /****************************************/
-        silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding );
+        silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
 
         /* Loop over quantizer and entropy coding to control bitrate */
         maxIter = 6;
@@ -194,17 +191,21 @@
                 /* Noise shaping quantization            */
                 /*****************************************/
                 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
-                    silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
-                           sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
+                    silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
+                           sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
                            psEnc->sCmn.arch );
                 } else {
-                    silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
-                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
+                    silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
+                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
                             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
                             psEnc->sCmn.arch);
                 }
 
+                if ( iter == maxIter && !found_lower ) {
+                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
+                }
+
                 /****************************************/
                 /* Encode Parameters                    */
                 /****************************************/
@@ -218,6 +219,33 @@
 
                 nBits = ec_tell( psRangeEnc );
 
+                /* If we still bust after the last iteration, do some damage control. */
+                if ( iter == maxIter && !found_lower && nBits > maxBits ) {
+                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
+
+                    /* Keep gains the same as the last frame. */
+                    psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
+                    for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+                        psEnc->sCmn.indices.GainsIndices[ i ] = 4;
+                    }
+                    if (condCoding != CODE_CONDITIONALLY) {
+                       psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
+                    }
+                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
+                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
+                    /* Clear all pulses. */
+                    for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
+                        psEnc->sCmn.pulses[ i ] = 0;
+                    }
+
+                    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
+
+                    silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
+                        psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
+
+                    nBits = ec_tell( psRangeEnc );
+                }
+
                 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
                     break;
                 }
@@ -265,15 +293,35 @@
                 break;
             }
 
+            if ( !found_lower && nBits > maxBits ) {
+                int j;
+                for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+                    int sum=0;
+                    for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
+                        sum += abs( psEnc->sCmn.pulses[j] );
+                    }
+                    if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
+                        best_sum[i] = sum;
+                        best_gain_mult[i] = gainMult_Q8;
+                    } else {
+                        gain_lock[i] = 1;
+                    }
+                }
+            }
             if( ( found_lower & found_upper ) == 0 ) {
                 /* Adjust gain according to high-rate rate/distortion curve */
-                opus_int32 gain_factor_Q16;
-                gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
-                gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
                 if( nBits > maxBits ) {
-                    gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
+                    if (gainMult_Q8 < 16384) {
+                        gainMult_Q8 *= 2;
+                    } else {
+                        gainMult_Q8 = 32767;
+                    }
+                } else {
+                    opus_int32 gain_factor_Q16;
+                    gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
+                    gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
                 }
-                gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
+
             } else {
                 /* Adjust gain by interpolating */
                 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
@@ -287,7 +335,13 @@
             }
 
             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
-                sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
+                opus_int16 tmp;
+                if ( gain_lock[i] ) {
+                    tmp = best_gain_mult[i];
+                } else {
+                    tmp = gainMult_Q8;
+                }
+                sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
             }
 
             /* Quantize gains */
@@ -331,7 +385,7 @@
 static OPUS_INLINE void silk_LBRR_encode_FIX(
     silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
     silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */
-    const opus_int32                xfw_Q3[],                               /* I    Input signal                                                                */
+    const opus_int16                x16[],                                  /* I    Input signal                                                                */
     opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */
 )
 {
@@ -370,14 +424,14 @@
         /* Noise shaping quantization            */
         /*****************************************/
         if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
-            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
+            silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
-                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+                psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
         } else {
-            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
+            silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
-                psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+                psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
         }
 
diff --git a/silk/fixed/find_LPC_FIX.c b/silk/fixed/find_LPC_FIX.c
index e11cdc8..e55b63a 100644
--- a/silk/fixed/find_LPC_FIX.c
+++ b/silk/fixed/find_LPC_FIX.c
@@ -92,7 +92,7 @@
             silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
 
             /* Convert to LPC for residual energy evaluation */
-            silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder );
+            silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
 
             /* Calculate residual energy with NLSF interpolation */
             silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );
diff --git a/silk/fixed/find_LTP_FIX.c b/silk/fixed/find_LTP_FIX.c
index 1314a28..62d4afb 100644
--- a/silk/fixed/find_LTP_FIX.c
+++ b/silk/fixed/find_LTP_FIX.c
@@ -32,214 +32,68 @@
 #include "main_FIX.h"
 #include "tuning_parameters.h"
 
-/* Head room for correlations */
-#define LTP_CORRS_HEAD_ROOM                             2
-
-void silk_fit_LTP(
-    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
-    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
-);
-
 void silk_find_LTP_FIX(
-    opus_int16                      b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                                                   */
-    opus_int32                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization                                           */
-    opus_int                        *LTPredCodGain_Q7,                      /* O    LTP coding gain                                                             */
-    const opus_int16                r_lpc[],                                /* I    residual signal after LPC signal + state for first 10 ms                    */
+    opus_int32                      XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Correlation matrix                                               */
+    opus_int32                      xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ],  /* O    Correlation vector                                                          */
+    const opus_int16                r_ptr[],                                /* I    Residual signal after LPC                                                   */
     const opus_int                  lag[ MAX_NB_SUBFR ],                    /* I    LTP lags                                                                    */
-    const opus_int32                Wght_Q15[ MAX_NB_SUBFR ],               /* I    weights                                                                     */
-    const opus_int                  subfr_length,                           /* I    subframe length                                                             */
-    const opus_int                  nb_subfr,                               /* I    number of subframes                                                         */
-    const opus_int                  mem_offset,                             /* I    number of samples in LTP memory                                             */
-    opus_int                        corr_rshifts[ MAX_NB_SUBFR ],           /* O    right shifts applied to correlations                                        */
+    const opus_int                  subfr_length,                           /* I    Subframe length                                                             */
+    const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */
     int                             arch                                    /* I    Run-time architecture                                                       */
 )
 {
-    opus_int   i, k, lshift;
-    const opus_int16 *r_ptr, *lag_ptr;
-    opus_int16 *b_Q14_ptr;
+    opus_int   i, k, extra_shifts;
+    opus_int   xx_shifts, xX_shifts, XX_shifts;
+    const opus_int16 *lag_ptr;
+    opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr;
+    opus_int32 xx, nrg, temp;
 
-    opus_int32 regu;
-    opus_int32 *WLTP_ptr;
-    opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26;
-    opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;
-
-    opus_int32 temp32, denom32;
-    opus_int   extra_shifts;
-    opus_int   rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;
-    opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;
-    opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
-    opus_int32 wd, m_Q12;
-
-    b_Q14_ptr = b_Q14;
-    WLTP_ptr  = WLTP;
-    r_ptr     = &r_lpc[ mem_offset ];
+    xXLTP_Q17_ptr = xXLTP_Q17;
+    XXLTP_Q17_ptr = XXLTP_Q17;
     for( k = 0; k < nb_subfr; k++ ) {
         lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
 
-        silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */
-
-        /* Assure headroom */
-        LZs = silk_CLZ32( rr[k] );
-        if( LZs < LTP_CORRS_HEAD_ROOM ) {
-            rr[ k ] = silk_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );
-            rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );
-        }
-        corr_rshifts[ k ] = rr_shifts;
-        silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ], arch );  /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */
-
-        /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */
-        silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ], arch );  /* Rr_fix_ptr   in Q( -corr_rshifts[ k ] ) */
-        if( corr_rshifts[ k ] > rr_shifts ) {
-            rr[ k ] = silk_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */
-        }
-        silk_assert( rr[ k ] >= 0 );
-
-        regu = 1;
-        regu = silk_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
-        regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
-        regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
-        silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );
-
-        silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */
-
-        /* Limit and store in Q14 */
-        silk_fit_LTP( b_Q16, b_Q14_ptr );
-
-        /* Calculate residual energy */
-        nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */
-
-        /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */
-        extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );
-        denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */
-            silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts );    /* Q( -corr_rshifts[ k ] + extra_shifts ) */
-        denom32 = silk_max( denom32, 1 );
-        silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX );                       /* Wght always < 0.5 in Q0 */
-        temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 );             /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
-        temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 );               /* Q26 */
-
-        /* Limit temp such that the below scaling never wraps around */
-        WLTP_max = 0;
-        for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
-            WLTP_max = silk_max( WLTP_ptr[ i ], WLTP_max );
-        }
-        lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
-        silk_assert( 26 - 18 + lshift >= 0 );
-        if( 26 - 18 + lshift < 31 ) {
-            temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) );
-        }
-
-        silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
-
-        w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */
-        silk_assert( w[k] >= 0 );
-
-        r_ptr     += subfr_length;
-        b_Q14_ptr += LTP_ORDER;
-        WLTP_ptr  += LTP_ORDER * LTP_ORDER;
-    }
-
-    maxRshifts = 0;
-    for( k = 0; k < nb_subfr; k++ ) {
-        maxRshifts = silk_max_int( corr_rshifts[ k ], maxRshifts );
-    }
-
-    /* Compute LTP coding gain */
-    if( LTPredCodGain_Q7 != NULL ) {
-        LPC_LTP_res_nrg = 0;
-        LPC_res_nrg     = 0;
-        silk_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */
-        for( k = 0; k < nb_subfr; k++ ) {
-            LPC_res_nrg     = silk_ADD32( LPC_res_nrg,     silk_RSHIFT( silk_ADD32( silk_SMULWB(  rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
-            LPC_LTP_res_nrg = silk_ADD32( LPC_LTP_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
-        }
-        LPC_LTP_res_nrg = silk_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */
-
-        div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );
-        *LTPredCodGain_Q7 = ( opus_int )silk_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) );
-
-        silk_assert( *LTPredCodGain_Q7 == ( opus_int )silk_SAT16( silk_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );
-    }
-
-    /* smoothing */
-    /* d = sum( B, 1 ); */
-    b_Q14_ptr = b_Q14;
-    for( k = 0; k < nb_subfr; k++ ) {
-        d_Q14[ k ] = 0;
-        for( i = 0; i < LTP_ORDER; i++ ) {
-            d_Q14[ k ] += b_Q14_ptr[ i ];
-        }
-        b_Q14_ptr += LTP_ORDER;
-    }
-
-    /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
-
-    /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */
-    max_abs_d_Q14 = 0;
-    max_w_bits    = 0;
-    for( k = 0; k < nb_subfr; k++ ) {
-        max_abs_d_Q14 = silk_max_32( max_abs_d_Q14, silk_abs( d_Q14[ k ] ) );
-        /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */
-        /* Find bits needed in Q( 18 - maxRshifts ) */
-        max_w_bits = silk_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );
-    }
-
-    /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -silk_int16_MIN */
-    silk_assert( max_abs_d_Q14 <= ( 5 << 15 ) );
-
-    /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */
-    extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14;
-
-    /* Subtract what we got available; bits in output var plus maxRshifts */
-    extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */
-    extra_shifts = silk_max_int( extra_shifts, 0 );
-
-    maxRshifts_wxtra = maxRshifts + extra_shifts;
-
-    temp32 = silk_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */
-    wd = 0;
-    for( k = 0; k < nb_subfr; k++ ) {
-        /* w has at least 2 bits of headroom so no overflow should happen */
-        temp32 = silk_ADD32( temp32,                     silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) );                      /* Q( 18 - maxRshifts_wxtra ) */
-        wd     = silk_ADD32( wd, silk_LSHIFT( silk_SMULWW( silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */
-    }
-    m_Q12 = silk_DIV32_varQ( wd, temp32, 12 );
-
-    b_Q14_ptr = b_Q14;
-    for( k = 0; k < nb_subfr; k++ ) {
-        /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */
-        if( 2 - corr_rshifts[k] > 0 ) {
-            temp32 = silk_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );
+        silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER );                            /* xx in Q( -xx_shifts ) */
+        silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, XXLTP_Q17_ptr, &nrg, &XX_shifts, arch );    /* XXLTP_Q17_ptr and nrg in Q( -XX_shifts ) */
+        extra_shifts = xx_shifts - XX_shifts;
+        if( extra_shifts > 0 ) {
+            /* Shift XX */
+            xX_shifts = xx_shifts;
+            for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
+                XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts );              /* Q( -xX_shifts ) */
+            }
+            nrg = silk_RSHIFT32( nrg, extra_shifts );                                                /* Q( -xX_shifts ) */
+        } else if( extra_shifts < 0 ) {
+            /* Shift xx */
+            xX_shifts = XX_shifts;
+            xx = silk_RSHIFT32( xx, -extra_shifts );                                                 /* Q( -xX_shifts ) */
         } else {
-            temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
+            xX_shifts = xx_shifts;
         }
+        silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch );    /* xXLTP_Q17_ptr in Q( -xX_shifts ) */
 
-        g_Q26 = silk_MUL(
-            silk_DIV32(
-                SILK_FIX_CONST( LTP_SMOOTHING, 26 ),
-                silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ),                          /* Q10 */
-            silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) );    /* Q16 */
-
-        temp32 = 0;
+        /* At this point all correlations are in Q(-xX_shifts) */
+        temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) );
+        temp = silk_max( temp, xx );
+TIC(div)
+#if 0
+        for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
+            XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 );
+        }
         for( i = 0; i < LTP_ORDER; i++ ) {
-            delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 );     /* 1638_Q14 = 0.1_Q0 */
-            temp32 += delta_b_Q14[ i ];                                 /* Q14 */
+            xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 );
         }
-        temp32 = silk_DIV32( g_Q26, temp32 );                           /* Q14 -> Q12 */
+#else
+        for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
+            XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp );
+        }
         for( i = 0; i < LTP_ORDER; i++ ) {
-            b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
+            xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp );
         }
-        b_Q14_ptr += LTP_ORDER;
-    }
-}
-
-void silk_fit_LTP(
-    opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
-    opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
-)
-{
-    opus_int i;
-
-    for( i = 0; i < LTP_ORDER; i++ ) {
-        LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
+#endif
+TOC(div)
+        r_ptr         += subfr_length;
+        XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER;
+        xXLTP_Q17_ptr += LTP_ORDER;
     }
 }
diff --git a/silk/fixed/find_pitch_lags_FIX.c b/silk/fixed/find_pitch_lags_FIX.c
index b8440a8..9303e9d 100644
--- a/silk/fixed/find_pitch_lags_FIX.c
+++ b/silk/fixed/find_pitch_lags_FIX.c
@@ -44,7 +44,7 @@
 {
     opus_int   buf_len, i, scale;
     opus_int32 thrhld_Q13, res_nrg;
-    const opus_int16 *x_buf, *x_buf_ptr;
+    const opus_int16 *x_ptr;
     VARDECL( opus_int16, Wsig );
     opus_int16 *Wsig_ptr;
     opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
@@ -61,8 +61,6 @@
     /* Safety check */
     silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
 
-    x_buf = x - psEnc->sCmn.ltp_mem_length;
-
     /*************************************/
     /* Estimate LPC AR coefficients      */
     /*************************************/
@@ -72,19 +70,19 @@
     ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
 
     /* First LA_LTP samples */
-    x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
+    x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length;
     Wsig_ptr  = Wsig;
-    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
+    silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch );
 
     /* Middle un - windowed samples */
     Wsig_ptr  += psEnc->sCmn.la_pitch;
-    x_buf_ptr += psEnc->sCmn.la_pitch;
-    silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
+    x_ptr += psEnc->sCmn.la_pitch;
+    silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
 
     /* Last LA_LTP samples */
     Wsig_ptr  += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
-    x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
-    silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
+    x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
+    silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch );
 
     /* Calculate autocorrelation sequence */
     silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );
@@ -112,7 +110,7 @@
     /*****************************************/
     /* LPC analysis filtering                */
     /*****************************************/
-    silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
+    silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
 
     if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
         /* Threshold for pitch estimator */
diff --git a/silk/fixed/find_pred_coefs_FIX.c b/silk/fixed/find_pred_coefs_FIX.c
index d308e9c..24c6aab 100644
--- a/silk/fixed/find_pred_coefs_FIX.c
+++ b/silk/fixed/find_pred_coefs_FIX.c
@@ -41,13 +41,12 @@
 )
 {
     opus_int         i;
-    opus_int32       invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];
+    opus_int32       invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ];
     opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];
     const opus_int16 *x_ptr;
     opus_int16       *x_pre_ptr;
     VARDECL( opus_int16, LPC_in_pre );
-    opus_int32       tmp, min_gain_Q16, minInvGain_Q30;
-    opus_int         LTP_corrs_rshift[ MAX_NB_SUBFR ];
+    opus_int32       min_gain_Q16, minInvGain_Q30;
     SAVE_STACK;
 
     /* weighting for weighted least squares */
@@ -61,13 +60,11 @@
         /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
         invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
 
-        /* Ensure Wght_Q15 a minimum value 1 */
-        invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 363 );
+        /* Limit inverse */
+        invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 );
 
         /* Square the inverted gains */
         silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );
-        tmp = silk_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );
-        Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 );
 
         /* Invert the inverted and normalized gains */
         local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
@@ -77,24 +74,24 @@
            psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
                + psEnc->sCmn.frame_length, opus_int16 );
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
-        VARDECL( opus_int32, WLTP );
+        VARDECL( opus_int32, xXLTP_Q17 );
+        VARDECL( opus_int32, XXLTP_Q17 );
 
         /**********/
         /* VOICED */
         /**********/
         silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
 
-        ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
+        ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
+        ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
 
         /* LTP analysis */
-        silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7,
-            res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length,
-            psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift, psEnc->sCmn.arch );
+        silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch,
+            psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
 
         /* Quantize LTP gain parameters */
         silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
-            &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,
-            psEnc->sCmn.arch);
+            &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
 
         /* Control LTP scaling */
         silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
diff --git a/silk/fixed/k2a_FIX.c b/silk/fixed/k2a_FIX.c
index 5fee599..549f6ea 100644
--- a/silk/fixed/k2a_FIX.c
+++ b/silk/fixed/k2a_FIX.c
@@ -39,14 +39,15 @@
 )
 {
     opus_int   k, n;
-    opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
+    opus_int32 rc, tmp1, tmp2;
 
     for( k = 0; k < order; k++ ) {
-        for( n = 0; n < k; n++ ) {
-            Atmp[ n ] = A_Q24[ n ];
-        }
-        for( n = 0; n < k; n++ ) {
-            A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
+        rc = rc_Q15[ k ];
+        for( n = 0; n < (k + 1) >> 1; n++ ) {
+            tmp1 = A_Q24[ n ];
+            tmp2 = A_Q24[ k - n - 1 ];
+            A_Q24[ n ]         = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc );
+            A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc );
         }
         A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
     }
diff --git a/silk/fixed/k2a_Q16_FIX.c b/silk/fixed/k2a_Q16_FIX.c
index 3b03987..1595aa6 100644
--- a/silk/fixed/k2a_Q16_FIX.c
+++ b/silk/fixed/k2a_Q16_FIX.c
@@ -39,15 +39,16 @@
 )
 {
     opus_int   k, n;
-    opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
+    opus_int32 rc, tmp1, tmp2;
 
     for( k = 0; k < order; k++ ) {
-        for( n = 0; n < k; n++ ) {
-            Atmp[ n ] = A_Q24[ n ];
+        rc = rc_Q16[ k ];
+        for( n = 0; n < (k + 1) >> 1; n++ ) {
+            tmp1 = A_Q24[ n ];
+            tmp2 = A_Q24[ k - n - 1 ];
+            A_Q24[ n ]         = silk_SMLAWW( tmp1, tmp2, rc );
+            A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc );
         }
-        for( n = 0; n < k; n++ ) {
-            A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );
-        }
-        A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 );
+        A_Q24[ k ] = -silk_LSHIFT( rc, 8 );
     }
 }
diff --git a/silk/fixed/main_FIX.h b/silk/fixed/main_FIX.h
index 375b5eb..780afa3 100644
--- a/silk/fixed/main_FIX.h
+++ b/silk/fixed/main_FIX.h
@@ -36,6 +36,11 @@
 #include "debug.h"
 #include "entenc.h"
 
+#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
+   || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
+#include "fixed/arm/warped_autocorrelation_FIX_arm.h"
+#endif
+
 #ifndef FORCE_CPP_BUILD
 #ifdef __cplusplus
 extern "C"
@@ -47,6 +52,9 @@
 #define silk_encode_do_VAD_Fxx      silk_encode_do_VAD_FIX
 #define silk_encode_frame_Fxx       silk_encode_frame_FIX
 
+#define QC  10
+#define QS  13
+
 /*********************/
 /* Encoder Functions */
 /*********************/
@@ -81,33 +89,11 @@
 opus_int silk_control_encoder(
     silk_encoder_state_Fxx          *psEnc,                                 /* I/O  Pointer to Silk encoder state                                               */
     silk_EncControlStruct           *encControl,                            /* I    Control structure                                                           */
-    const opus_int32                TargetRate_bps,                         /* I    Target max bitrate (bps)                                                    */
     const opus_int                  allow_bw_switch,                        /* I    Flag to allow switching audio bandwidth                                     */
     const opus_int                  channelNb,                              /* I    Channel number                                                              */
     const opus_int                  force_fs_kHz
 );
 
-/****************/
-/* Prefiltering */
-/****************/
-void silk_prefilter_FIX(
-    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state                                                               */
-    const silk_encoder_control_FIX  *psEncCtrl,                             /* I    Encoder control                                                             */
-    opus_int32                      xw_Q10[],                               /* O    Weighted signal                                                             */
-    const opus_int16                x[]                                     /* I    Speech signal                                                               */
-);
-
-void silk_warped_LPC_analysis_filter_FIX_c(
-          opus_int32            state[],                    /* I/O  State [order + 1]                   */
-          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */
-    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */
-    const opus_int16            input[],                    /* I    Input signal [length]               */
-    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */
-    const opus_int              length,                     /* I    Length of input signal              */
-    const opus_int              order                       /* I    Filter order (even)                 */
-);
-
-
 /**************************/
 /* Noise shaping analysis */
 /**************************/
@@ -121,7 +107,7 @@
 );
 
 /* Autocorrelations for a warped frequency axis */
-void silk_warped_autocorrelation_FIX(
+void silk_warped_autocorrelation_FIX_c(
           opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */
           opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */
     const opus_int16                *input,                                 /* I    Input data to correlate                                                     */
@@ -130,6 +116,11 @@
     const opus_int                  order                                   /* I    Correlation order (even)                                                    */
 );
 
+#if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
+#define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
+        ((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order))
+#endif
+
 /* Calculation of LTP state scaling */
 void silk_LTP_scale_ctrl_FIX(
     silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */
@@ -168,16 +159,12 @@
 
 /* LTP analysis */
 void silk_find_LTP_FIX(
-    opus_int16                      b_Q14[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                                                   */
-    opus_int32                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization                                           */
-    opus_int                        *LTPredCodGain_Q7,                      /* O    LTP coding gain                                                             */
-    const opus_int16                r_lpc[],                                /* I    residual signal after LPC signal + state for first 10 ms                    */
+    opus_int32                      XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Correlation matrix                                               */
+    opus_int32                      xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ],  /* O    Correlation vector                                                          */
+    const opus_int16                r_lpc[],                                /* I    Residual signal after LPC                                                   */
     const opus_int                  lag[ MAX_NB_SUBFR ],                    /* I    LTP lags                                                                    */
-    const opus_int32                Wght_Q15[ MAX_NB_SUBFR ],               /* I    weights                                                                     */
-    const opus_int                  subfr_length,                           /* I    subframe length                                                             */
-    const opus_int                  nb_subfr,                               /* I    number of subframes                                                         */
-    const opus_int                  mem_offset,                             /* I    number of samples in LTP memory                                             */
-    opus_int                        corr_rshifts[ MAX_NB_SUBFR ],           /* O    right shifts applied to correlations                                        */
+    const opus_int                  subfr_length,                           /* I    Subframe length                                                             */
+    const opus_int                  nb_subfr,                               /* I    Number of subframes                                                         */
     int                             arch                                    /* I    Run-time architecture                                                       */
 );
 
@@ -231,9 +218,9 @@
     const opus_int16                *x,                                     /* I    x vector [L + order - 1] used to form data matrix X                         */
     const opus_int                  L,                                      /* I    Length of vectors                                                           */
     const opus_int                  order,                                  /* I    Max lag for correlation                                                     */
-    const opus_int                  head_room,                              /* I    Desired headroom                                                            */
     opus_int32                      *XX,                                    /* O    Pointer to X'*X correlation matrix [ order x order ]                        */
-    opus_int                        *rshifts,                               /* I/O  Right shifts of correlations                                                */
+    opus_int32                      *nrg,                                   /* O    Energy of x vector                                                          */
+    opus_int                        *rshifts,                               /* O    Right shifts of correlations                                                */
     int                              arch                                   /* I    Run-time architecture                                                       */
 );
 
@@ -248,22 +235,6 @@
     int                             arch                                    /* I    Run-time architecture                                                       */
 );
 
-/* Add noise to matrix diagonal */
-void silk_regularize_correlations_FIX(
-    opus_int32                      *XX,                                    /* I/O  Correlation matrices                                                        */
-    opus_int32                      *xx,                                    /* I/O  Correlation values                                                          */
-    opus_int32                      noise,                                  /* I    Noise to add                                                                */
-    opus_int                        D                                       /* I    Dimension of XX                                                             */
-);
-
-/* Solves Ax = b, assuming A is symmetric */
-void silk_solve_LDL_FIX(
-    opus_int32                      *A,                                     /* I    Pointer to symetric square matrix A                                         */
-    opus_int                        M,                                      /* I    Size of matrix                                                              */
-    const opus_int32                *b,                                     /* I    Pointer to b vector                                                         */
-    opus_int32                      *x_Q16                                  /* O    Pointer to x solution vector                                                */
-);
-
 #ifndef FORCE_CPP_BUILD
 #ifdef __cplusplus
 }
diff --git a/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h b/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
index c30481e..3999b5b 100644
--- a/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
+++ b/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
@@ -169,7 +169,7 @@
 
         if( psEnc->sCmn.warping_Q16 > 0 ) {
             /* Calculate warped auto correlation */
-            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
+            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
         } else {
             /* Calculate regular auto correlation */
             silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
@@ -224,8 +224,8 @@
         silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
 
         /* Ratio of prediction gains, in energy domain */
-        pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
-        nrg         = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
+        pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch );
+        nrg         = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch );
 
         /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
         pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
diff --git a/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h b/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
index e803ef0..fcbd96c 100644
--- a/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
+++ b/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
@@ -48,7 +48,8 @@
     const opus_int16                *input,                                 /* I    Input data to correlate                                                     */
     const opus_int                  warping_Q16,                            /* I    Warping coefficient                                                         */
     const opus_int                  length,                                 /* I    Length of input                                                             */
-    const opus_int                  order                                   /* I    Correlation order (even)                                                    */
+    const opus_int                  order,                                  /* I    Correlation order (even)                                                    */
+    int                             arch                                    /* I    Run-time architecture                                                       */
 )
 {
     opus_int   n, i, lsh;
diff --git a/silk/fixed/noise_shape_analysis_FIX.c b/silk/fixed/noise_shape_analysis_FIX.c
index 22a89f7..85fea0b 100644
--- a/silk/fixed/noise_shape_analysis_FIX.c
+++ b/silk/fixed/noise_shape_analysis_FIX.c
@@ -57,88 +57,79 @@
 /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */
 /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
 static OPUS_INLINE void limit_warped_coefs(
-    opus_int32           *coefs_syn_Q24,
-    opus_int32           *coefs_ana_Q24,
+    opus_int32           *coefs_Q24,
     opus_int             lambda_Q16,
     opus_int32           limit_Q24,
     opus_int             order
 ) {
     opus_int   i, iter, ind = 0;
-    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;
+    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
     opus_int32 nom_Q16, den_Q24;
+    opus_int32 limit_Q20, maxabs_Q20;
 
     /* Convert to monic coefficients */
     lambda_Q16 = -lambda_Q16;
     for( i = order - 1; i > 0; i-- ) {
-        coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
-        coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+        coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
     }
     lambda_Q16 = -lambda_Q16;
-    nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16,        lambda_Q16 );
-    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
-    gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
-    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
-    gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+    nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
+    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
+    gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
     for( i = 0; i < order; i++ ) {
-        coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
-        coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+        coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
     }
-
+    limit_Q20 = silk_RSHIFT(limit_Q24, 4);
     for( iter = 0; iter < 10; iter++ ) {
         /* Find maximum absolute value */
         maxabs_Q24 = -1;
         for( i = 0; i < order; i++ ) {
-            tmp = silk_max( silk_abs_int32( coefs_syn_Q24[ i ] ), silk_abs_int32( coefs_ana_Q24[ i ] ) );
+            tmp = silk_abs_int32( coefs_Q24[ i ] );
             if( tmp > maxabs_Q24 ) {
                 maxabs_Q24 = tmp;
                 ind = i;
             }
         }
-        if( maxabs_Q24 <= limit_Q24 ) {
+        /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
+        maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
+        if( maxabs_Q20 <= limit_Q20 ) {
             /* Coefficients are within range - done */
             return;
         }
 
         /* Convert back to true warped coefficients */
         for( i = 1; i < order; i++ ) {
-            coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
-            coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+            coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
         }
-        gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );
-        gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );
+        gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
         for( i = 0; i < order; i++ ) {
-            coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
-            coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+            coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
         }
 
         /* Apply bandwidth expansion */
         chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
-            silk_SMULWB( maxabs_Q24 - limit_Q24, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
-            silk_MUL( maxabs_Q24, ind + 1 ), 22 );
-        silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );
-        silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );
+            silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
+            silk_MUL( maxabs_Q20, ind + 1 ), 22 );
+        silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
 
         /* Convert to monic warped coefficients */
         lambda_Q16 = -lambda_Q16;
         for( i = order - 1; i > 0; i-- ) {
-            coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
-            coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
+            coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
         }
         lambda_Q16 = -lambda_Q16;
         nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16,        lambda_Q16 );
-        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
-        gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
-        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
-        gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
+        gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
         for( i = 0; i < order; i++ ) {
-            coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
-            coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
+            coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
         }
     }
     silk_assert( 0 );
 }
 
-#if defined(MIPSr1_ASM)
+/* Disable MIPS version until it's updated. */
+#if 0 && defined(MIPSr1_ASM)
 #include "mips/noise_shape_analysis_FIX_mipsr1.h"
 #endif
 
@@ -155,14 +146,13 @@
 )
 {
     silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
-    opus_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
-    opus_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
-    opus_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
-    opus_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
+    opus_int     k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
+    opus_int32   SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
+    opus_int32   nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
+    opus_int32   BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
     opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];
     opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
-    opus_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];
-    opus_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];
+    opus_int32   AR_Q24[       MAX_SHAPE_LPC_ORDER ];
     VARDECL( opus_int16, x_windowed );
     const opus_int16 *x_ptr, *pitch_res_ptr;
     SAVE_STACK;
@@ -209,14 +199,14 @@
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
         /* Initially set to 0; may be overruled in process_gains(..) */
         psEnc->sCmn.indices.quantOffsetType = 0;
-        psEncCtrl->sparseness_Q8 = 0;
     } else {
         /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
         nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
         energy_variation_Q7 = 0;
         log_energy_prev_Q7  = 0;
         pitch_res_ptr = pitch_res;
-        for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
+        nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
+        for( k = 0; k < nSegs; k++ ) {
             silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
             nrg += silk_RSHIFT( nSamples, scale );           /* Q(-scale)*/
 
@@ -228,18 +218,12 @@
             pitch_res_ptr += nSamples;
         }
 
-        psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
-            SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
-
         /* Set quantization offset depending on sparseness measure */
-        if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
+        if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
             psEnc->sCmn.indices.quantOffsetType = 0;
         } else {
             psEnc->sCmn.indices.quantOffsetType = 1;
         }
-
-        /* Increase coding SNR for sparse signals */
-        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );
     }
 
     /*******************************/
@@ -247,14 +231,8 @@
     /*******************************/
     /* More BWE for signals with high prediction gain */
     strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
-    BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
+    BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
         silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
-    delta_Q16  = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
-        SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
-    BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
-    BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
-    /* BWExp1 will be applied after BWExp2, so make it relative */
-    BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
 
     if( psEnc->sCmn.warping_Q16 > 0 ) {
         /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
@@ -284,7 +262,7 @@
 
         if( psEnc->sCmn.warping_Q16 > 0 ) {
             /* Calculate warped auto correlation */
-            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
+            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
         } else {
             /* Calculate regular auto correlation */
             silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
@@ -299,7 +277,7 @@
         silk_assert( nrg >= 0 );
 
         /* Convert reflection coefficients to prediction coefficients */
-        silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
+        silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
 
         Qnrg = -scale;          /* range: -12...30*/
         silk_assert( Qnrg >= -12 );
@@ -318,40 +296,34 @@
 
         if( psEnc->sCmn.warping_Q16 > 0 ) {
             /* Adjust gain for warping */
-            gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
-            silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
-            if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
-               psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
+            gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
+            silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
+            if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
+                psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
             } else {
-               psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
+                psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
+                if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
+                    psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
+                } else {
+                    psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
+                }
             }
+            silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
         }
 
-        /* Bandwidth expansion for synthesis filter shaping */
-        silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
+        /* Bandwidth expansion */
+        silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
 
-        /* Compute noise shaping filter coefficients */
-        silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
+        if( psEnc->sCmn.warping_Q16 > 0 ) {
+            /* Convert to monic warped prediction coefficients and limit absolute values */
+            limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
 
-        /* Bandwidth expansion for analysis filter shaping */
-        silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
-        silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
-
-        /* Ratio of prediction gains, in energy domain */
-        pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
-        nrg         = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
-
-        /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
-        pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
-        psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
-
-        /* Convert to monic warped prediction coefficients and limit absolute values */
-        limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
-
-        /* Convert from Q24 to Q13 and store in int16 */
-        for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
-            psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
-            psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
+            /* Convert from Q24 to Q13 and store in int16 */
+            for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
+                psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
+            }
+        } else {
+            silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
         }
     }
 
@@ -368,11 +340,6 @@
         psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
     }
 
-    gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
-        psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
-        psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
-    }
 
     /************************************************/
     /* Control low-frequency shaping and noise tilt */
@@ -410,14 +377,6 @@
     /****************************/
     /* HARMONIC SHAPING CONTROL */
     /****************************/
-    /* Control boosting of harmonic frequencies */
-    HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
-        psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
-
-    /* More harmonic boost for noisy input signals */
-    HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
-        SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
-
     if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
         /* More harmonic noise shaping for high bitrates or noisy input */
         HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
@@ -435,14 +394,11 @@
     /* Smooth over subframes */
     /*************************/
     for( k = 0; k < MAX_NB_SUBFR; k++ ) {
-        psShapeSt->HarmBoost_smth_Q16 =
-            silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16,     HarmBoost_Q16     - psShapeSt->HarmBoost_smth_Q16,     SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
         psShapeSt->HarmShapeGain_smth_Q16 =
             silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
         psShapeSt->Tilt_smth_Q16 =
             silk_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
 
-        psEncCtrl->HarmBoost_Q14[ k ]     = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16,     2 );
         psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
         psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );
     }
diff --git a/silk/fixed/pitch_analysis_core_FIX.c b/silk/fixed/pitch_analysis_core_FIX.c
index 01bb9fc..8df109e 100644
--- a/silk/fixed/pitch_analysis_core_FIX.c
+++ b/silk/fixed/pitch_analysis_core_FIX.c
@@ -80,7 +80,7 @@
 /*      FIXED POINT CORE PITCH ANALYSIS FUNCTION             */
 /*************************************************************/
 opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0 voiced, 1 unvoiced                      */
-    const opus_int16            *frame,             /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */
+    const opus_int16            *frame_unscaled,    /* I    Signal of length PE_FRAME_LENGTH_MS*Fs_kHz                  */
     opus_int                    *pitch_out,         /* O    4 pitch lag values                                          */
     opus_int16                  *lagIndex,          /* O    Lag Index                                                   */
     opus_int8                   *contourIndex,      /* O    Pitch contour Index                                         */
@@ -94,16 +94,17 @@
     int                         arch                /* I    Run-time architecture                                       */
 )
 {
-    VARDECL( opus_int16, frame_8kHz );
+    VARDECL( opus_int16, frame_8kHz_buf );
     VARDECL( opus_int16, frame_4kHz );
+    VARDECL( opus_int16, frame_scaled );
     opus_int32 filt_state[ 6 ];
-    const opus_int16 *input_frame_ptr;
+    const opus_int16 *frame, *frame_8kHz;
     opus_int   i, k, d, j;
     VARDECL( opus_int16, C );
     VARDECL( opus_int32, xcorr32 );
     const opus_int16 *target_ptr, *basis_ptr;
-    opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
-    opus_int   d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;
+    opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target;
+    opus_int   d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift;
     VARDECL( opus_int16, d_comp );
     opus_int32 sum, threshold, lag_counter;
     opus_int   CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
@@ -119,6 +120,7 @@
     opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
     const opus_int8 *Lag_CB_ptr;
     SAVE_STACK;
+
     /* Check for valid sampling frequency */
     silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
 
@@ -137,17 +139,33 @@
     min_lag           = PE_MIN_LAG_MS * Fs_kHz;
     max_lag           = PE_MAX_LAG_MS * Fs_kHz - 1;
 
+    /* Downscale input if necessary */
+    silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length );
+    shift += 3 - silk_CLZ32( energy );        /* at least two bits headroom */
+    ALLOC( frame_scaled, frame_length, opus_int16 );
+    if( shift > 0 ) {
+        shift = silk_RSHIFT( shift + 1, 1 );
+        for( i = 0; i < frame_length; i++ ) {
+            frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift );
+        }
+        frame = frame_scaled;
+    } else {
+        frame = frame_unscaled;
+    }
+
+    ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 );
     /* Resample from input sampled at Fs_kHz to 8 kHz */
-    ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 );
     if( Fs_kHz == 16 ) {
         silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
-        silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );
+        silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length );
+        frame_8kHz = frame_8kHz_buf;
     } else if( Fs_kHz == 12 ) {
         silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
-        silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length );
+        silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
+        frame_8kHz = frame_8kHz_buf;
     } else {
         silk_assert( Fs_kHz == 8 );
-        silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );
+        frame_8kHz = frame;
     }
 
     /* Decimate again to 4 kHz */
@@ -160,19 +178,6 @@
         frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
     }
 
-    /*******************************************************************************
-    ** Scale 4 kHz signal down to prevent correlations measures from overflowing
-    ** find scaling as max scaling for each 8kHz(?) subframe
-    *******************************************************************************/
-
-    /* Inner product is calculated with different lengths, so scale for the worst case */
-    silk_sum_sqr_shift( &energy, &shift, frame_4kHz, frame_length_4kHz );
-    if( shift > 0 ) {
-        shift = silk_RSHIFT( shift, 1 );
-        for( i = 0; i < frame_length_4kHz; i++ ) {
-            frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift );
-        }
-    }
 
     /******************************************************************************
     * FIRST STAGE, operating in 4 khz
@@ -311,18 +316,6 @@
     ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
     *************************************************************************************/
 
-    /******************************************************************************
-    ** Scale signal down to avoid correlations measures from overflowing
-    *******************************************************************************/
-    /* find scaling as max scaling for each subframe */
-    silk_sum_sqr_shift( &energy, &shift, frame_8kHz, frame_length_8kHz );
-    if( shift > 0 ) {
-        shift = silk_RSHIFT( shift, 1 );
-        for( i = 0; i < frame_length_8kHz; i++ ) {
-            frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift );
-        }
-    }
-
     /*********************************************************************************
     * Find energy of each subframe projected onto its history, for a range of delays
     *********************************************************************************/
@@ -462,24 +455,6 @@
     silk_assert( *LTPCorr_Q15 >= 0 );
 
     if( Fs_kHz > 8 ) {
-        VARDECL( opus_int16, scratch_mem );
-        /***************************************************************************/
-        /* Scale input signal down to avoid correlations measures from overflowing */
-        /***************************************************************************/
-        /* find scaling as max scaling for each subframe */
-        silk_sum_sqr_shift( &energy, &shift, frame, frame_length );
-        ALLOC( scratch_mem, shift > 0 ? frame_length : ALLOC_NONE, opus_int16 );
-        if( shift > 0 ) {
-            /* Move signal to scratch mem because the input signal should be unchanged */
-            shift = silk_RSHIFT( shift, 1 );
-            for( i = 0; i < frame_length; i++ ) {
-                scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift );
-            }
-            input_frame_ptr = scratch_mem;
-        } else {
-            input_frame_ptr = frame;
-        }
-
         /* Search in original signal */
 
         CBimax_old = CBimax;
@@ -519,14 +494,14 @@
         /* Calculate the correlations and energies needed in stage 3 */
         ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
         ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
-        silk_P_Ana_calc_corr_st3(  cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );
-        silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );
+        silk_P_Ana_calc_corr_st3(  cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
+        silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
 
         lag_counter = 0;
         silk_assert( lag == silk_SAT16( lag ) );
         contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
 
-        target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
+        target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
         energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );
         for( d = start_lag; d <= end_lag; d++ ) {
             for( j = 0; j < nb_cbk_search; j++ ) {
diff --git a/silk/fixed/prefilter_FIX.c b/silk/fixed/prefilter_FIX.c
deleted file mode 100644
index 6a8e351..0000000
--- a/silk/fixed/prefilter_FIX.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/***********************************************************************
-Copyright (c) 2006-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "main_FIX.h"
-#include "stack_alloc.h"
-#include "tuning_parameters.h"
-
-#if defined(MIPSr1_ASM)
-#include "mips/prefilter_FIX_mipsr1.h"
-#endif
-
-
-#if !defined(OVERRIDE_silk_warped_LPC_analysis_filter_FIX)
-#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
-    ((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
-#endif
-
-/* Prefilter for finding Quantizer input signal */
-static OPUS_INLINE void silk_prefilt_FIX(
-    silk_prefilter_state_FIX    *P,                         /* I/O  state                               */
-    opus_int32                  st_res_Q12[],               /* I    short term residual signal          */
-    opus_int32                  xw_Q3[],                    /* O    prefiltered signal                  */
-    opus_int32                  HarmShapeFIRPacked_Q12,     /* I    Harmonic shaping coeficients        */
-    opus_int                    Tilt_Q14,                   /* I    Tilt shaping coeficient             */
-    opus_int32                  LF_shp_Q14,                 /* I    Low-frequancy shaping coeficients   */
-    opus_int                    lag,                        /* I    Lag for harmonic shaping            */
-    opus_int                    length                      /* I    Length of signals                   */
-);
-
-void silk_warped_LPC_analysis_filter_FIX_c(
-          opus_int32            state[],                    /* I/O  State [order + 1]                   */
-          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */
-    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */
-    const opus_int16            input[],                    /* I    Input signal [length]               */
-    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */
-    const opus_int              length,                     /* I    Length of input signal              */
-    const opus_int              order                       /* I    Filter order (even)                 */
-)
-{
-    opus_int     n, i;
-    opus_int32   acc_Q11, tmp1, tmp2;
-
-    /* Order must be even */
-    silk_assert( ( order & 1 ) == 0 );
-
-    for( n = 0; n < length; n++ ) {
-        /* Output of lowpass section */
-        tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
-        state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
-        /* Output of allpass section */
-        tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
-        state[ 1 ] = tmp2;
-        acc_Q11 = silk_RSHIFT( order, 1 );
-        acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
-        /* Loop over allpass sections */
-        for( i = 2; i < order; i += 2 ) {
-            /* Output of allpass section */
-            tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
-            state[ i ] = tmp1;
-            acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
-            /* Output of allpass section */
-            tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
-            state[ i + 1 ] = tmp2;
-            acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
-        }
-        state[ order ] = tmp1;
-        acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
-        res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
-    }
-}
-
-void silk_prefilter_FIX(
-    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state                                                               */
-    const silk_encoder_control_FIX  *psEncCtrl,                             /* I    Encoder control                                                             */
-    opus_int32                      xw_Q3[],                                /* O    Weighted signal                                                             */
-    const opus_int16                x[]                                     /* I    Speech signal                                                               */
-)
-{
-    silk_prefilter_state_FIX *P = &psEnc->sPrefilt;
-    opus_int   j, k, lag;
-    opus_int32 tmp_32;
-    const opus_int16 *AR1_shp_Q13;
-    const opus_int16 *px;
-    opus_int32 *pxw_Q3;
-    opus_int   HarmShapeGain_Q12, Tilt_Q14;
-    opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
-    VARDECL( opus_int32, x_filt_Q12 );
-    VARDECL( opus_int32, st_res_Q2 );
-    opus_int16 B_Q10[ 2 ];
-    SAVE_STACK;
-
-    /* Set up pointers */
-    px  = x;
-    pxw_Q3 = xw_Q3;
-    lag = P->lagPrev;
-    ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 );
-    ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 );
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
-        /* Update Variables that change per sub frame */
-        if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
-            lag = psEncCtrl->pitchL[ k ];
-        }
-
-        /* Noise shape parameters */
-        HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
-        silk_assert( HarmShapeGain_Q12 >= 0 );
-        HarmShapeFIRPacked_Q12  =                          silk_RSHIFT( HarmShapeGain_Q12, 2 );
-        HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
-        Tilt_Q14    = psEncCtrl->Tilt_Q14[   k ];
-        LF_shp_Q14  = psEncCtrl->LF_shp_Q14[ k ];
-        AR1_shp_Q13 = &psEncCtrl->AR1_Q13[   k * MAX_SHAPE_LPC_ORDER ];
-
-        /* Short term FIR filtering*/
-        silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px,
-            psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder, psEnc->sCmn.arch );
-
-        /* Reduce (mainly) low frequencies during harmonic emphasis */
-        B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 );
-        tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 );   /* Q26 */
-        tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) );    /* Q26 */
-        tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] );                                                /* Q24 */
-        tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 );                                                                     /* Q10 */
-        B_Q10[ 1 ]= silk_SAT16( tmp_32 );
-        x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] );
-        for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
-            x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] );
-        }
-        P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ];
-
-        silk_prefilt_FIX( P, x_filt_Q12, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
-
-        px  += psEnc->sCmn.subfr_length;
-        pxw_Q3 += psEnc->sCmn.subfr_length;
-    }
-
-    P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
-    RESTORE_STACK;
-}
-
-#ifndef OVERRIDE_silk_prefilt_FIX
-/* Prefilter for finding Quantizer input signal */
-static OPUS_INLINE void silk_prefilt_FIX(
-    silk_prefilter_state_FIX    *P,                         /* I/O  state                               */
-    opus_int32                  st_res_Q12[],               /* I    short term residual signal          */
-    opus_int32                  xw_Q3[],                    /* O    prefiltered signal                  */
-    opus_int32                  HarmShapeFIRPacked_Q12,     /* I    Harmonic shaping coeficients        */
-    opus_int                    Tilt_Q14,                   /* I    Tilt shaping coeficient             */
-    opus_int32                  LF_shp_Q14,                 /* I    Low-frequancy shaping coeficients   */
-    opus_int                    lag,                        /* I    Lag for harmonic shaping            */
-    opus_int                    length                      /* I    Length of signals                   */
-)
-{
-    opus_int   i, idx, LTP_shp_buf_idx;
-    opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
-    opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
-    opus_int16 *LTP_shp_buf;
-
-    /* To speed up use temp variables instead of using the struct */
-    LTP_shp_buf     = P->sLTP_shp;
-    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
-    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;
-    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;
-
-    for( i = 0; i < length; i++ ) {
-        if( lag > 0 ) {
-            /* unrolled loop */
-            silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
-            idx = lag + LTP_shp_buf_idx;
-            n_LTP_Q12 = silk_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
-            n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
-            n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
-        } else {
-            n_LTP_Q12 = 0;
-        }
-
-        n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
-        n_LF_Q10   = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
-
-        sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
-        sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12,  silk_LSHIFT( n_LF_Q10,   2 ) );
-
-        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
-        LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
-
-        xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
-    }
-
-    /* Copy temp variable back to state */
-    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;
-    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;
-    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
-}
-#endif /* OVERRIDE_silk_prefilt_FIX */
diff --git a/silk/fixed/schur64_FIX.c b/silk/fixed/schur64_FIX.c
index 764a10e..b2cb12d 100644
--- a/silk/fixed/schur64_FIX.c
+++ b/silk/fixed/schur64_FIX.c
@@ -43,7 +43,7 @@
     opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
     opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
 
-    silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
+    silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
 
     /* Check for invalid input */
     if( c[ 0 ] <= 0 ) {
@@ -51,9 +51,10 @@
         return 0;
     }
 
-    for( k = 0; k < order + 1; k++ ) {
+    k = 0;
+    do {
         C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
-    }
+    } while( ++k <= order );
 
     for( k = 0; k < order; k++ ) {
         /* Check that we won't be getting an unstable rc, otherwise stop here. */
diff --git a/silk/fixed/schur_FIX.c b/silk/fixed/schur_FIX.c
index c4c0ef2..59d44a6 100644
--- a/silk/fixed/schur_FIX.c
+++ b/silk/fixed/schur_FIX.c
@@ -43,28 +43,29 @@
     opus_int32    C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
     opus_int32    Ctmp1, Ctmp2, rc_tmp_Q15;
 
-    silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
+    silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
 
     /* Get number of leading zeros */
     lz = silk_CLZ32( c[ 0 ] );
 
     /* Copy correlations and adjust level to Q30 */
+    k = 0;
     if( lz < 2 ) {
         /* lz must be 1, so shift one to the right */
-        for( k = 0; k < order + 1; k++ ) {
+        do {
             C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
-        }
+        } while( ++k <= order );
     } else if( lz > 2 ) {
         /* Shift to the left */
         lz -= 2;
-        for( k = 0; k < order + 1; k++ ) {
+        do {
             C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
-        }
+        } while( ++k <= order );
     } else {
         /* No need to shift */
-        for( k = 0; k < order + 1; k++ ) {
+        do {
             C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
-        }
+        } while( ++k <= order );
     }
 
     for( k = 0; k < order; k++ ) {
diff --git a/silk/fixed/solve_LS_FIX.c b/silk/fixed/solve_LS_FIX.c
deleted file mode 100644
index 51d7d49..0000000
--- a/silk/fixed/solve_LS_FIX.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/***********************************************************************
-Copyright (c) 2006-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "main_FIX.h"
-#include "stack_alloc.h"
-#include "tuning_parameters.h"
-
-/*****************************/
-/* Internal function headers */
-/*****************************/
-
-typedef struct {
-    opus_int32 Q36_part;
-    opus_int32 Q48_part;
-} inv_D_t;
-
-/* Factorize square matrix A into LDL form */
-static OPUS_INLINE void silk_LDL_factorize_FIX(
-    opus_int32          *A,         /* I/O Pointer to Symetric Square Matrix                            */
-    opus_int            M,          /* I   Size of Matrix                                               */
-    opus_int32          *L_Q16,     /* I/O Pointer to Square Upper triangular Matrix                    */
-    inv_D_t             *inv_D      /* I/O Pointer to vector holding inverted diagonal elements of D    */
-);
-
-/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
-static OPUS_INLINE void silk_LS_SolveFirst_FIX(
-    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */
-    opus_int            M,          /* I    Dim of Matrix equation                                      */
-    const opus_int32    *b,         /* I    b Vector                                                    */
-    opus_int32          *x_Q16      /* O    x Vector                                                    */
-);
-
-/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
-static OPUS_INLINE void silk_LS_SolveLast_FIX(
-    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */
-    const opus_int      M,          /* I    Dim of Matrix equation                                      */
-    const opus_int32    *b,         /* I    b Vector                                                    */
-    opus_int32          *x_Q16      /* O    x Vector                                                    */
-);
-
-static OPUS_INLINE void silk_LS_divide_Q16_FIX(
-    opus_int32          T[],        /* I/O  Numenator vector                                            */
-    inv_D_t             *inv_D,     /* I    1 / D vector                                                */
-    opus_int            M           /* I    dimension                                                   */
-);
-
-/* Solves Ax = b, assuming A is symmetric */
-void silk_solve_LDL_FIX(
-    opus_int32                      *A,                                     /* I    Pointer to symetric square matrix A                                         */
-    opus_int                        M,                                      /* I    Size of matrix                                                              */
-    const opus_int32                *b,                                     /* I    Pointer to b vector                                                         */
-    opus_int32                      *x_Q16                                  /* O    Pointer to x solution vector                                                */
-)
-{
-    VARDECL( opus_int32, L_Q16 );
-    opus_int32 Y[      MAX_MATRIX_SIZE ];
-    inv_D_t   inv_D[  MAX_MATRIX_SIZE ];
-    SAVE_STACK;
-
-    silk_assert( M <= MAX_MATRIX_SIZE );
-    ALLOC( L_Q16, M * M, opus_int32 );
-
-    /***************************************************
-    Factorize A by LDL such that A = L*D*L',
-    where L is lower triangular with ones on diagonal
-    ****************************************************/
-    silk_LDL_factorize_FIX( A, M, L_Q16, inv_D );
-
-    /****************************************************
-    * substitute D*L'*x = Y. ie:
-    L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b
-    ******************************************************/
-    silk_LS_SolveFirst_FIX( L_Q16, M, b, Y );
-
-    /****************************************************
-    D*L'*x = Y <=> L'*x = inv(D)*Y, because D is
-    diagonal just multiply with 1/d_i
-    ****************************************************/
-    silk_LS_divide_Q16_FIX( Y, inv_D, M );
-
-    /****************************************************
-    x = inv(L') * inv(D) * Y
-    *****************************************************/
-    silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 );
-    RESTORE_STACK;
-}
-
-static OPUS_INLINE void silk_LDL_factorize_FIX(
-    opus_int32          *A,         /* I/O Pointer to Symetric Square Matrix                            */
-    opus_int            M,          /* I   Size of Matrix                                               */
-    opus_int32          *L_Q16,     /* I/O Pointer to Square Upper triangular Matrix                    */
-    inv_D_t             *inv_D      /* I/O Pointer to vector holding inverted diagonal elements of D    */
-)
-{
-    opus_int   i, j, k, status, loop_count;
-    const opus_int32 *ptr1, *ptr2;
-    opus_int32 diag_min_value, tmp_32, err;
-    opus_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ];
-    opus_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48;
-
-    silk_assert( M <= MAX_MATRIX_SIZE );
-
-    status = 1;
-    diag_min_value = silk_max_32( silk_SMMUL( silk_ADD_SAT32( A[ 0 ], A[ silk_SMULBB( M, M ) - 1 ] ), SILK_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 );
-    for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) {
-        status = 0;
-        for( j = 0; j < M; j++ ) {
-            ptr1 = matrix_adr( L_Q16, j, 0, M );
-            tmp_32 = 0;
-            for( i = 0; i < j; i++ ) {
-                v_Q0[ i ] = silk_SMULWW(         D_Q0[ i ], ptr1[ i ] ); /* Q0 */
-                tmp_32    = silk_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */
-            }
-            tmp_32 = silk_SUB32( matrix_ptr( A, j, j, M ), tmp_32 );
-
-            if( tmp_32 < diag_min_value ) {
-                tmp_32 = silk_SUB32( silk_SMULBB( loop_count + 1, diag_min_value ), tmp_32 );
-                /* Matrix not positive semi-definite, or ill conditioned */
-                for( i = 0; i < M; i++ ) {
-                    matrix_ptr( A, i, i, M ) = silk_ADD32( matrix_ptr( A, i, i, M ), tmp_32 );
-                }
-                status = 1;
-                break;
-            }
-            D_Q0[ j ] = tmp_32;                         /* always < max(Correlation) */
-
-            /* two-step division */
-            one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 );                    /* Q36 */
-            one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 );                   /* Q40 */
-            err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) );     /* Q24 */
-            one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 );                 /* Q48 */
-
-            /* Save 1/Ds */
-            inv_D[ j ].Q36_part = one_div_diag_Q36;
-            inv_D[ j ].Q48_part = one_div_diag_Q48;
-
-            matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */
-            ptr1 = matrix_adr( A, j, 0, M );
-            ptr2 = matrix_adr( L_Q16, j + 1, 0, M );
-            for( i = j + 1; i < M; i++ ) {
-                tmp_32 = 0;
-                for( k = 0; k < j; k++ ) {
-                    tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */
-                }
-                tmp_32 = silk_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */
-
-                /* tmp_32 / D_Q0[j] : Divide to Q16 */
-                matrix_ptr( L_Q16, i, j, M ) = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ),
-                    silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
-
-                /* go to next column */
-                ptr2 += M;
-            }
-        }
-    }
-
-    silk_assert( status == 0 );
-}
-
-static OPUS_INLINE void silk_LS_divide_Q16_FIX(
-    opus_int32          T[],        /* I/O  Numenator vector                                            */
-    inv_D_t             *inv_D,     /* I    1 / D vector                                                */
-    opus_int            M           /* I    dimension                                                   */
-)
-{
-    opus_int   i;
-    opus_int32 tmp_32;
-    opus_int32 one_div_diag_Q36, one_div_diag_Q48;
-
-    for( i = 0; i < M; i++ ) {
-        one_div_diag_Q36 = inv_D[ i ].Q36_part;
-        one_div_diag_Q48 = inv_D[ i ].Q48_part;
-
-        tmp_32 = T[ i ];
-        T[ i ] = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
-    }
-}
-
-/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
-static OPUS_INLINE void silk_LS_SolveFirst_FIX(
-    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */
-    opus_int            M,          /* I    Dim of Matrix equation                                      */
-    const opus_int32    *b,         /* I    b Vector                                                    */
-    opus_int32          *x_Q16      /* O    x Vector                                                    */
-)
-{
-    opus_int i, j;
-    const opus_int32 *ptr32;
-    opus_int32 tmp_32;
-
-    for( i = 0; i < M; i++ ) {
-        ptr32 = matrix_adr( L_Q16, i, 0, M );
-        tmp_32 = 0;
-        for( j = 0; j < i; j++ ) {
-            tmp_32 = silk_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] );
-        }
-        x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
-    }
-}
-
-/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
-static OPUS_INLINE void silk_LS_SolveLast_FIX(
-    const opus_int32    *L_Q16,     /* I    Pointer to Lower Triangular Matrix                          */
-    const opus_int      M,          /* I    Dim of Matrix equation                                      */
-    const opus_int32    *b,         /* I    b Vector                                                    */
-    opus_int32          *x_Q16      /* O    x Vector                                                    */
-)
-{
-    opus_int i, j;
-    const opus_int32 *ptr32;
-    opus_int32 tmp_32;
-
-    for( i = M - 1; i >= 0; i-- ) {
-        ptr32 = matrix_adr( L_Q16, 0, i, M );
-        tmp_32 = 0;
-        for( j = M - 1; j > i; j-- ) {
-            tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] );
-        }
-        x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
-    }
-}
diff --git a/silk/fixed/structs_FIX.h b/silk/fixed/structs_FIX.h
index 3294b25..2774a97 100644
--- a/silk/fixed/structs_FIX.h
+++ b/silk/fixed/structs_FIX.h
@@ -48,30 +48,16 @@
 } silk_shape_state_FIX;
 
 /********************************/
-/* Prefilter state              */
-/********************************/
-typedef struct {
-    opus_int16                  sLTP_shp[ LTP_BUF_LENGTH ];
-    opus_int32                  sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];
-    opus_int                    sLTP_shp_buf_idx;
-    opus_int32                  sLF_AR_shp_Q12;
-    opus_int32                  sLF_MA_shp_Q12;
-    opus_int32                  sHarmHP_Q2;
-    opus_int32                  rand_seed;
-    opus_int                    lagPrev;
-} silk_prefilter_state_FIX;
-
-/********************************/
 /* Encoder state FIX            */
 /********************************/
 typedef struct {
     silk_encoder_state          sCmn;                                   /* Common struct, shared with floating-point code       */
     silk_shape_state_FIX        sShape;                                 /* Shape state                                          */
-    silk_prefilter_state_FIX    sPrefilt;                               /* Prefilter State                                      */
 
     /* Buffer for find pitch and noise shape analysis */
     silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis  */
     opus_int                    LTPCorr_Q15;                            /* Normalized correlation from pitch lag estimator      */
+    opus_int32                    resNrgSmth;
 } silk_encoder_state_FIX;
 
 /************************/
@@ -87,11 +73,8 @@
 
     /* Noise shaping parameters */
     /* Testing */
-    silk_DWORD_ALIGN opus_int16 AR1_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
-    silk_DWORD_ALIGN opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+    silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
     opus_int32                  LF_shp_Q14[        MAX_NB_SUBFR ];      /* Packs two int16 coefficients per int32 value         */
-    opus_int                    GainsPre_Q14[      MAX_NB_SUBFR ];
-    opus_int                    HarmBoost_Q14[     MAX_NB_SUBFR ];
     opus_int                    Tilt_Q14[          MAX_NB_SUBFR ];
     opus_int                    HarmShapeGain_Q14[ MAX_NB_SUBFR ];
     opus_int                    Lambda_Q10;
@@ -99,7 +82,6 @@
     opus_int                    coding_quality_Q14;
 
     /* measures */
-    opus_int                    sparseness_Q8;
     opus_int32                  predGain_Q16;
     opus_int                    LTPredCodGain_Q7;
     opus_int32                  ResNrg[ MAX_NB_SUBFR ];                 /* Residual energy per subframe                         */
diff --git a/silk/fixed/warped_autocorrelation_FIX.c b/silk/fixed/warped_autocorrelation_FIX.c
index 6ca6c11..994c299 100644
--- a/silk/fixed/warped_autocorrelation_FIX.c
+++ b/silk/fixed/warped_autocorrelation_FIX.c
@@ -31,17 +31,13 @@
 
 #include "main_FIX.h"
 
-#define QC  10
-#define QS  14
-
 #if defined(MIPSr1_ASM)
 #include "mips/warped_autocorrelation_FIX_mipsr1.h"
 #endif
 
 
-#ifndef OVERRIDE_silk_warped_autocorrelation_FIX
 /* Autocorrelations for a warped frequency axis */
-void silk_warped_autocorrelation_FIX(
+void silk_warped_autocorrelation_FIX_c(
           opus_int32                *corr,                                  /* O    Result [order + 1]                                                          */
           opus_int                  *scale,                                 /* O    Scaling of the correlation vector                                           */
     const opus_int16                *input,                                 /* I    Input data to correlate                                                     */
@@ -92,4 +88,3 @@
     }
     silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
 }
-#endif /* OVERRIDE_silk_warped_autocorrelation_FIX */
diff --git a/silk/fixed/x86/prefilter_FIX_sse.c b/silk/fixed/x86/prefilter_FIX_sse.c
index 488a603..d8c9c2f 100644
--- a/silk/fixed/x86/prefilter_FIX_sse.c
+++ b/silk/fixed/x86/prefilter_FIX_sse.c
@@ -107,8 +107,8 @@
                 xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );
                 xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );
 
-                sum  = (coef_Q13_8 * state_8) >> 16;
-                sum += (coef_Q13_9 * state_9) >> 16;
+                sum  = (opus_int32)((coef_Q13_8 * state_8) >> 16);
+                sum += (opus_int32)((coef_Q13_9 * state_9) >> 16);
 
                 xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
                 sum += _mm_cvtsi128_si32( xmm_tempa);
diff --git a/silk/float/LPC_inv_pred_gain_FLP.c b/silk/float/LPC_inv_pred_gain_FLP.c
index 25178ba..2be2122 100644
--- a/silk/float/LPC_inv_pred_gain_FLP.c
+++ b/silk/float/LPC_inv_pred_gain_FLP.c
@@ -31,8 +31,7 @@
 
 #include "SigProc_FIX.h"
 #include "SigProc_FLP.h"
-
-#define RC_THRESHOLD        0.9999f
+#include "define.h"
 
 /* compute inverse of LPC prediction gain, and                          */
 /* test if LPC coefficients are stable (all poles within unit circle)   */
@@ -43,34 +42,32 @@
 )
 {
     opus_int   k, n;
-    double     invGain, rc, rc_mult1, rc_mult2;
-    silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];
-    silk_float *Aold, *Anew;
+    double     invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2;
+    silk_float Atmp[ SILK_MAX_ORDER_LPC ];
 
-    Anew = Atmp[ order & 1 ];
-    silk_memcpy( Anew, A, order * sizeof(silk_float) );
+    silk_memcpy( Atmp, A, order * sizeof(silk_float) );
 
     invGain = 1.0;
     for( k = order - 1; k > 0; k-- ) {
-        rc = -Anew[ k ];
-        if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
+        rc = -Atmp[ k ];
+        rc_mult1 = 1.0f - rc * rc;
+        invGain *= rc_mult1;
+        if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
             return 0.0f;
         }
-        rc_mult1 = 1.0f - rc * rc;
         rc_mult2 = 1.0f / rc_mult1;
-        invGain *= rc_mult1;
-        /* swap pointers */
-        Aold = Anew;
-        Anew = Atmp[ k & 1 ];
-        for( n = 0; n < k; n++ ) {
-            Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 );
+        for( n = 0; n < (k + 1) >> 1; n++ ) {
+            tmp1 = Atmp[ n ];
+            tmp2 = Atmp[ k - n - 1 ];
+            Atmp[ n ]         = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 );
+            Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 );
         }
     }
-    rc = -Anew[ 0 ];
-    if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
-        return 0.0f;
-    }
+    rc = -Atmp[ 0 ];
     rc_mult1 = 1.0f - rc * rc;
     invGain *= rc_mult1;
+    if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
+        return 0.0f;
+    }
     return (silk_float)invGain;
 }
diff --git a/silk/float/SigProc_FLP.h b/silk/float/SigProc_FLP.h
index f0cb373..953de8b 100644
--- a/silk/float/SigProc_FLP.h
+++ b/silk/float/SigProc_FLP.h
@@ -68,13 +68,6 @@
     opus_int32          order               /* I     prediction order                                           */
 );
 
-/* Solve the normal equations using the Levinson-Durbin recursion */
-silk_float silk_levinsondurbin_FLP(         /* O    prediction error energy                                     */
-    silk_float          A[],                /* O    prediction coefficients [order]                             */
-    const silk_float    corr[],             /* I    input auto-correlations [order + 1]                         */
-    const opus_int      order               /* I    prediction order                                            */
-);
-
 /* compute autocorrelation */
 void silk_autocorrelation_FLP(
     silk_float          *results,           /* O    result (length correlationCount)                            */
diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c
index 2092a4d..c3ad50a 100644
--- a/silk/float/encode_frame_FLP.c
+++ b/silk/float/encode_frame_FLP.c
@@ -29,6 +29,7 @@
 #include "config.h"
 #endif
 
+#include <stdlib.h>
 #include "main_FLP.h"
 #include "tuning_parameters.h"
 
@@ -85,7 +86,6 @@
     silk_encoder_control_FLP sEncCtrl;
     opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
     silk_float   *x_frame, *res_pitch_frame;
-    silk_float   xfw[ MAX_FRAME_LENGTH ];
     silk_float   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
     ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
     silk_nsq_state sNSQ_copy, sNSQ_copy2;
@@ -97,6 +97,9 @@
     opus_int8    LastGainIndex_copy2;
     opus_int32   pGains_Q16[ MAX_NB_SUBFR ];
     opus_uint8   ec_buf_copy[ 1275 ];
+    opus_int     gain_lock[ MAX_NB_SUBFR ] = {0};
+    opus_int16   best_gain_mult[ MAX_NB_SUBFR ];
+    opus_int     best_sum[ MAX_NB_SUBFR ];
 
     /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
     LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
@@ -139,22 +142,17 @@
         /***************************************************/
         /* Find linear prediction coefficients (LPC + LTP) */
         /***************************************************/
-        silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
+        silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
 
         /****************************************/
         /* Process gains                        */
         /****************************************/
         silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
 
-        /*****************************************/
-        /* Prefiltering for noise shaper         */
-        /*****************************************/
-        silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );
-
         /****************************************/
         /* Low Bitrate Redundant Encoding       */
         /****************************************/
-        silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );
+        silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding );
 
         /* Loop over quantizer and entroy coding to control bitrate */
         maxIter = 6;
@@ -188,7 +186,11 @@
                 /*****************************************/
                 /* Noise shaping quantization            */
                 /*****************************************/
-                silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );
+                silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
+
+                if ( iter == maxIter && !found_lower ) {
+                    silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
+                }
 
                 /****************************************/
                 /* Encode Parameters                    */
@@ -203,6 +205,33 @@
 
                 nBits = ec_tell( psRangeEnc );
 
+                /* If we still bust after the last iteration, do some damage control. */
+                if ( iter == maxIter && !found_lower && nBits > maxBits ) {
+                    silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
+
+                    /* Keep gains the same as the last frame. */
+                    psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
+                    for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+                        psEnc->sCmn.indices.GainsIndices[ i ] = 4;
+                    }
+                    if (condCoding != CODE_CONDITIONALLY) {
+                       psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
+                    }
+                    psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
+                    psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
+                    /* Clear all pulses. */
+                    for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
+                        psEnc->sCmn.pulses[ i ] = 0;
+                    }
+
+                    silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
+
+                    silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
+                        psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
+
+                    nBits = ec_tell( psRangeEnc );
+                }
+
                 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
                     break;
                 }
@@ -223,7 +252,9 @@
             if( nBits > maxBits ) {
                 if( found_lower == 0 && iter >= 2 ) {
                     /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
-                    sEncCtrl.Lambda *= 1.5f;
+                    sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
+                    /* Reducing dithering can help us hit the target. */
+                    psEnc->sCmn.indices.quantOffsetType = 0;
                     found_upper = 0;
                     gainsID_upper = -1;
                 } else {
@@ -250,15 +281,34 @@
                 break;
             }
 
+            if ( !found_lower && nBits > maxBits ) {
+                int j;
+                for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
+                    int sum=0;
+                    for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
+                        sum += abs( psEnc->sCmn.pulses[j] );
+                    }
+                    if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
+                        best_sum[i] = sum;
+                        best_gain_mult[i] = gainMult_Q8;
+                    } else {
+                        gain_lock[i] = 1;
+                    }
+                }
+            }
             if( ( found_lower & found_upper ) == 0 ) {
                 /* Adjust gain according to high-rate rate/distortion curve */
-                opus_int32 gain_factor_Q16;
-                gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
-                gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
                 if( nBits > maxBits ) {
-                    gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
+                    if (gainMult_Q8 < 16384) {
+                        gainMult_Q8 *= 2;
+                    } else {
+                        gainMult_Q8 = 32767;
+                    }
+                } else {
+                    opus_int32 gain_factor_Q16;
+                    gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
+                    gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
                 }
-                gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
             } else {
                 /* Adjust gain by interpolating */
                 gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
@@ -272,7 +322,13 @@
             }
 
             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
-                pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
+                opus_int16 tmp;
+                if ( gain_lock[i] ) {
+                    tmp = best_gain_mult[i];
+                } else {
+                    tmp = gainMult_Q8;
+                }
+                pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
             }
 
             /* Quantize gains */
diff --git a/silk/float/energy_FLP.c b/silk/float/energy_FLP.c
index 24b8179..7bc7173 100644
--- a/silk/float/energy_FLP.c
+++ b/silk/float/energy_FLP.c
@@ -37,13 +37,12 @@
     opus_int            dataSize
 )
 {
-    opus_int  i, dataSize4;
+    opus_int i;
     double   result;
 
     /* 4x unrolled loop */
     result = 0.0;
-    dataSize4 = dataSize & 0xFFFC;
-    for( i = 0; i < dataSize4; i += 4 ) {
+    for( i = 0; i < dataSize - 3; i += 4 ) {
         result += data[ i + 0 ] * (double)data[ i + 0 ] +
                   data[ i + 1 ] * (double)data[ i + 1 ] +
                   data[ i + 2 ] * (double)data[ i + 2 ] +
diff --git a/silk/float/find_LPC_FLP.c b/silk/float/find_LPC_FLP.c
index fcfe1c3..4d63964 100644
--- a/silk/float/find_LPC_FLP.c
+++ b/silk/float/find_LPC_FLP.c
@@ -73,7 +73,7 @@
             silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
 
             /* Convert to LPC for residual energy evaluation */
-            silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );
+            silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
 
             /* Calculate residual energy with LSF interpolation */
             silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
diff --git a/silk/float/find_LTP_FLP.c b/silk/float/find_LTP_FLP.c
index 7229996..f970649 100644
--- a/silk/float/find_LTP_FLP.c
+++ b/silk/float/find_LTP_FLP.c
@@ -33,100 +33,32 @@
 #include "tuning_parameters.h"
 
 void silk_find_LTP_FLP(
-    silk_float                      b[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                   */
-    silk_float                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization       */
-    silk_float                      *LTPredCodGain,                     /* O    LTP coding gain                             */
-    const silk_float                r_lpc[],                            /* I    LPC residual                                */
-    const opus_int                  lag[  MAX_NB_SUBFR ],               /* I    LTP lags                                    */
-    const silk_float                Wght[ MAX_NB_SUBFR ],               /* I    Weights                                     */
+    silk_float                      XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization         */
+    silk_float                      xX[ MAX_NB_SUBFR * LTP_ORDER ],     /* O    Weight for LTP quantization                 */
+    const silk_float                r_ptr[],                            /* I    LPC residual                                */
+    const opus_int                  lag[ MAX_NB_SUBFR ],                /* I    LTP lags                                    */
     const opus_int                  subfr_length,                       /* I    Subframe length                             */
-    const opus_int                  nb_subfr,                           /* I    number of subframes                         */
-    const opus_int                  mem_offset                          /* I    Number of samples in LTP memory             */
+    const opus_int                  nb_subfr                            /* I    number of subframes                         */
 )
 {
-    opus_int   i, k;
-    silk_float *b_ptr, temp, *WLTP_ptr;
-    silk_float LPC_res_nrg, LPC_LTP_res_nrg;
-    silk_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ];
-    silk_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu;
-    silk_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
-    const silk_float *r_ptr, *lag_ptr;
+    opus_int   k;
+    silk_float *xX_ptr, *XX_ptr;
+    const silk_float *lag_ptr;
+    silk_float xx, temp;
 
-    b_ptr    = b;
-    WLTP_ptr = WLTP;
-    r_ptr    = &r_lpc[ mem_offset ];
+    xX_ptr = xX;
+    XX_ptr = XX;
     for( k = 0; k < nb_subfr; k++ ) {
         lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
+        silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr );
+        silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr );
+        xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER );
+        temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f );
+        silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER );
+        silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER );
 
-        silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr );
-        silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr );
-
-        rr[ k ] = ( silk_float )silk_energy_FLP( r_ptr, subfr_length );
-        regu = 1.0f + rr[ k ] +
-            matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) +
-            matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER );
-        regu *= LTP_DAMPING / 3;
-        silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER );
-        silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr );
-
-        /* Calculate residual energy */
-        nrg[ k ] = silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER );
-
-        temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length );
-        silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER );
-        w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER );
-
-        r_ptr    += subfr_length;
-        b_ptr    += LTP_ORDER;
-        WLTP_ptr += LTP_ORDER * LTP_ORDER;
-    }
-
-    /* Compute LTP coding gain */
-    if( LTPredCodGain != NULL ) {
-        LPC_LTP_res_nrg = 1e-6f;
-        LPC_res_nrg     = 0.0f;
-        for( k = 0; k < nb_subfr; k++ ) {
-            LPC_res_nrg     += rr[  k ] * Wght[ k ];
-            LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ];
-        }
-
-        silk_assert( LPC_LTP_res_nrg > 0 );
-        *LTPredCodGain = 3.0f * silk_log2( LPC_res_nrg / LPC_LTP_res_nrg );
-    }
-
-    /* Smoothing */
-    /* d = sum( B, 1 ); */
-    b_ptr = b;
-    for( k = 0; k < nb_subfr; k++ ) {
-        d[ k ] = 0;
-        for( i = 0; i < LTP_ORDER; i++ ) {
-            d[ k ] += b_ptr[ i ];
-        }
-        b_ptr += LTP_ORDER;
-    }
-    /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
-    temp = 1e-3f;
-    for( k = 0; k < nb_subfr; k++ ) {
-        temp += w[ k ];
-    }
-    m = 0;
-    for( k = 0; k < nb_subfr; k++ ) {
-        m += d[ k ] * w[ k ];
-    }
-    m = m / temp;
-
-    b_ptr = b;
-    for( k = 0; k < nb_subfr; k++ ) {
-        g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] );
-        temp = 0;
-        for( i = 0; i < LTP_ORDER; i++ ) {
-            delta_b[ i ] = silk_max_float( b_ptr[ i ], 0.1f );
-            temp += delta_b[ i ];
-        }
-        temp = g / temp;
-        for( i = 0; i < LTP_ORDER; i++ ) {
-            b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp;
-        }
-        b_ptr += LTP_ORDER;
+        r_ptr  += subfr_length;
+        XX_ptr += LTP_ORDER * LTP_ORDER;
+        xX_ptr += LTP_ORDER;
     }
 }
diff --git a/silk/float/find_pred_coefs_FLP.c b/silk/float/find_pred_coefs_FLP.c
index 1af4fe5..cb2e763 100644
--- a/silk/float/find_pred_coefs_FLP.c
+++ b/silk/float/find_pred_coefs_FLP.c
@@ -41,8 +41,9 @@
 )
 {
     opus_int         i;
-    silk_float       WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
-    silk_float       invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ];
+    silk_float       XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
+    silk_float       xXLTP[ MAX_NB_SUBFR * LTP_ORDER ];
+    silk_float       invGains[ MAX_NB_SUBFR ];
     opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];
     const silk_float *x_ptr;
     silk_float       *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
@@ -52,7 +53,6 @@
     for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
         silk_assert( psEncCtrl->Gains[ i ] > 0.0f );
         invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];
-        Wght[ i ]     = invGains[ i ] * invGains[ i ];
     }
 
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
@@ -62,13 +62,11 @@
         silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
 
         /* LTP analysis */
-        silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch,
-            psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length );
+        silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
 
         /* Quantize LTP gain parameters */
         silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
-            &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,
-            psEnc->sCmn.arch );
+            &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
 
         /* Control LTP scaling */
         silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding );
diff --git a/silk/float/inner_product_FLP.c b/silk/float/inner_product_FLP.c
index 029c012..cdd39d2 100644
--- a/silk/float/inner_product_FLP.c
+++ b/silk/float/inner_product_FLP.c
@@ -38,13 +38,12 @@
     opus_int            dataSize
 )
 {
-    opus_int  i, dataSize4;
+    opus_int i;
     double   result;
 
     /* 4x unrolled loop */
     result = 0.0;
-    dataSize4 = dataSize & 0xFFFC;
-    for( i = 0; i < dataSize4; i += 4 ) {
+    for( i = 0; i < dataSize - 3; i += 4 ) {
         result += data1[ i + 0 ] * (double)data2[ i + 0 ] +
                   data1[ i + 1 ] * (double)data2[ i + 1 ] +
                   data1[ i + 2 ] * (double)data2[ i + 2 ] +
diff --git a/silk/float/k2a_FLP.c b/silk/float/k2a_FLP.c
index 12af4e7..1448008 100644
--- a/silk/float/k2a_FLP.c
+++ b/silk/float/k2a_FLP.c
@@ -39,15 +39,16 @@
 )
 {
     opus_int   k, n;
-    silk_float Atmp[ SILK_MAX_ORDER_LPC ];
+    silk_float rck, tmp1, tmp2;
 
     for( k = 0; k < order; k++ ) {
-        for( n = 0; n < k; n++ ) {
-            Atmp[ n ] = A[ n ];
+        rck = rc[ k ];
+        for( n = 0; n < (k + 1) >> 1; n++ ) {
+            tmp1 = A[ n ];
+            tmp2 = A[ k - n - 1 ];
+            A[ n ]         = tmp1 + tmp2 * rck;
+            A[ k - n - 1 ] = tmp2 + tmp1 * rck;
         }
-        for( n = 0; n < k; n++ ) {
-            A[ n ] += Atmp[ k - n - 1 ] * rc[ k ];
-        }
-        A[ k ] = -rc[ k ];
+        A[ k ] = -rck;
     }
 }
diff --git a/silk/float/levinsondurbin_FLP.c b/silk/float/levinsondurbin_FLP.c
deleted file mode 100644
index f0ba606..0000000
--- a/silk/float/levinsondurbin_FLP.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/***********************************************************************
-Copyright (c) 2006-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FLP.h"
-
-/* Solve the normal equations using the Levinson-Durbin recursion */
-silk_float silk_levinsondurbin_FLP(         /* O    prediction error energy                                     */
-    silk_float          A[],                /* O    prediction coefficients    [order]                          */
-    const silk_float    corr[],             /* I    input auto-correlations [order + 1]                         */
-    const opus_int      order               /* I    prediction order                                            */
-)
-{
-    opus_int   i, mHalf, m;
-    silk_float min_nrg, nrg, t, km, Atmp1, Atmp2;
-
-    min_nrg = 1e-12f * corr[ 0 ] + 1e-9f;
-    nrg = corr[ 0 ];
-    nrg = silk_max_float(min_nrg, nrg);
-    A[ 0 ] = corr[ 1 ] / nrg;
-    nrg -= A[ 0 ] * corr[ 1 ];
-    nrg = silk_max_float(min_nrg, nrg);
-
-    for( m = 1; m < order; m++ )
-    {
-        t = corr[ m + 1 ];
-        for( i = 0; i < m; i++ ) {
-            t -= A[ i ] * corr[ m - i ];
-        }
-
-        /* reflection coefficient */
-        km = t / nrg;
-
-        /* residual energy */
-        nrg -= km * t;
-        nrg = silk_max_float(min_nrg, nrg);
-
-        mHalf = m >> 1;
-        for( i = 0; i < mHalf; i++ ) {
-            Atmp1 = A[ i ];
-            Atmp2 = A[ m - i - 1 ];
-            A[ m - i - 1 ] -= km * Atmp1;
-            A[ i ]         -= km * Atmp2;
-        }
-        if( m & 1 ) {
-            A[ mHalf ]     -= km * A[ mHalf ];
-        }
-        A[ m ] = km;
-    }
-
-    /* return the residual energy */
-    return nrg;
-}
-
diff --git a/silk/float/main_FLP.h b/silk/float/main_FLP.h
index e5a7597..f47fc93 100644
--- a/silk/float/main_FLP.h
+++ b/silk/float/main_FLP.h
@@ -79,22 +79,11 @@
 opus_int silk_control_encoder(
     silk_encoder_state_FLP          *psEnc,                             /* I/O  Pointer to Silk encoder state FLP           */
     silk_EncControlStruct           *encControl,                        /* I    Control structure                           */
-    const opus_int32                TargetRate_bps,                     /* I    Target max bitrate (bps)                    */
     const opus_int                  allow_bw_switch,                    /* I    Flag to allow switching audio bandwidth     */
     const opus_int                  channelNb,                          /* I    Channel number                              */
     const opus_int                  force_fs_kHz
 );
 
-/****************/
-/* Prefiltering */
-/****************/
-void silk_prefilter_FLP(
-    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
-    const silk_encoder_control_FLP  *psEncCtrl,                         /* I    Encoder control FLP                         */
-    silk_float                      xw[],                               /* O    Weighted signal                             */
-    const silk_float                x[]                                 /* I    Speech signal                               */
-);
-
 /**************************/
 /* Noise shaping analysis */
 /**************************/
@@ -153,15 +142,12 @@
 
 /* LTP analysis */
 void silk_find_LTP_FLP(
-    silk_float                      b[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    LTP coefs                                   */
-    silk_float                      WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization       */
-    silk_float                      *LTPredCodGain,                     /* O    LTP coding gain                             */
-    const silk_float                r_lpc[],                            /* I    LPC residual                                */
+    silk_float                      XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O    Weight for LTP quantization         */
+    silk_float                      xX[ MAX_NB_SUBFR * LTP_ORDER ],     /* O    Weight for LTP quantization                 */
+    const silk_float                r_ptr[],                            /* I    LPC residual                                */
     const opus_int                  lag[  MAX_NB_SUBFR ],               /* I    LTP lags                                    */
-    const silk_float                Wght[ MAX_NB_SUBFR ],               /* I    Weights                                     */
     const opus_int                  subfr_length,                       /* I    Subframe length                             */
-    const opus_int                  nb_subfr,                           /* I    number of subframes                         */
-    const opus_int                  mem_offset                          /* I    Number of samples in LTP memory             */
+    const opus_int                  nb_subfr                            /* I    number of subframes                         */
 );
 
 void silk_LTP_analysis_filter_FLP(
@@ -198,14 +184,15 @@
 
 /* LTP tap quantizer */
 void silk_quant_LTP_gains_FLP(
-    silk_float                      B[ MAX_NB_SUBFR * LTP_ORDER ],      /* I/O  (Un-)quantized LTP gains                    */
+    silk_float                      B[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    Quantized LTP gains                         */
     opus_int8                       cbk_index[ MAX_NB_SUBFR ],          /* O    Codebook index                              */
     opus_int8                       *periodicity_index,                 /* O    Periodicity index                           */
     opus_int32                      *sum_log_gain_Q7,                   /* I/O  Cumulative max prediction gain  */
-    const silk_float                W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I    Error weights                        */
-    const opus_int                  mu_Q10,                             /* I    Mu value (R/D tradeoff)                     */
-    const opus_int                  lowComplexity,                      /* I    Flag for low complexity                     */
-    const opus_int                  nb_subfr,                           /* I    number of subframes                         */
+    silk_float                      *pred_gain_dB,                      /* O    LTP prediction gain                         */
+    const silk_float                XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I    Correlation matrix                  */
+    const silk_float                xX[ MAX_NB_SUBFR * LTP_ORDER ],     /* I    Correlation vector                          */
+    const opus_int                  subfr_len,                          /* I    Number of samples per subframe              */
+    const opus_int                  nb_subfr,                           /* I    Number of subframes                         */
     int                             arch                                /* I    Run-time architecture                       */
 );
 
@@ -245,22 +232,6 @@
     silk_float                      *Xt                                 /* O    X'*t correlation vector [order]             */
 );
 
-/* Add noise to matrix diagonal */
-void silk_regularize_correlations_FLP(
-    silk_float                      *XX,                                /* I/O  Correlation matrices                        */
-    silk_float                      *xx,                                /* I/O  Correlation values                          */
-    const silk_float                noise,                              /* I    Noise energy to add                         */
-    const opus_int                  D                                   /* I    Dimension of XX                             */
-);
-
-/* Function to solve linear equation Ax = b, where A is an MxM symmetric matrix */
-void silk_solve_LDL_FLP(
-    silk_float                      *A,                                 /* I/O  Symmetric square matrix, out: reg.          */
-    const opus_int                  M,                                  /* I    Size of matrix                              */
-    const silk_float                *b,                                 /* I    Pointer to b vector                         */
-    silk_float                      *x                                  /* O    Pointer to x solution vector                */
-);
-
 /* Apply sine window to signal vector.  */
 /* Window types:                        */
 /*  1 -> sine window from 0 to pi/2     */
@@ -285,7 +256,8 @@
 void silk_NLSF2A_FLP(
     silk_float                      *pAR,                               /* O    LPC coefficients [ LPC_order ]              */
     const opus_int16                *NLSF_Q15,                          /* I    NLSF vector      [ LPC_order ]              */
-    const opus_int                  LPC_order                           /* I    LPC order                                   */
+    const opus_int                  LPC_order,                          /* I    LPC order                                   */
+    int                             arch                                /* I    Run-time architecture                       */
 );
 
 /* Limit, stabilize, and quantize NLSFs */
diff --git a/silk/float/noise_shape_analysis_FLP.c b/silk/float/noise_shape_analysis_FLP.c
index 65f6ea5..cb3d8a5 100644
--- a/silk/float/noise_shape_analysis_FLP.c
+++ b/silk/float/noise_shape_analysis_FLP.c
@@ -55,25 +55,21 @@
 /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */
 /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
 static OPUS_INLINE void warped_true2monic_coefs(
-    silk_float           *coefs_syn,
-    silk_float           *coefs_ana,
+    silk_float           *coefs,
     silk_float           lambda,
     silk_float           limit,
     opus_int             order
 ) {
     opus_int   i, iter, ind = 0;
-    silk_float tmp, maxabs, chirp, gain_syn, gain_ana;
+    silk_float tmp, maxabs, chirp, gain;
 
     /* Convert to monic coefficients */
     for( i = order - 1; i > 0; i-- ) {
-        coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
-        coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
+        coefs[ i - 1 ] -= lambda * coefs[ i ];
     }
-    gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
-    gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
+    gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
     for( i = 0; i < order; i++ ) {
-        coefs_syn[ i ] *= gain_syn;
-        coefs_ana[ i ] *= gain_ana;
+        coefs[ i ] *= gain;
     }
 
     /* Limit */
@@ -81,7 +77,7 @@
         /* Find maximum absolute value */
         maxabs = -1.0f;
         for( i = 0; i < order; i++ ) {
-            tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) );
+            tmp = silk_abs_float( coefs[ i ] );
             if( tmp > maxabs ) {
                 maxabs = tmp;
                 ind = i;
@@ -94,36 +90,59 @@
 
         /* Convert back to true warped coefficients */
         for( i = 1; i < order; i++ ) {
-            coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ];
-            coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ];
+            coefs[ i - 1 ] += lambda * coefs[ i ];
         }
-        gain_syn = 1.0f / gain_syn;
-        gain_ana = 1.0f / gain_ana;
+        gain = 1.0f / gain;
         for( i = 0; i < order; i++ ) {
-            coefs_syn[ i ] *= gain_syn;
-            coefs_ana[ i ] *= gain_ana;
+            coefs[ i ] *= gain;
         }
 
         /* Apply bandwidth expansion */
         chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
-        silk_bwexpander_FLP( coefs_syn, order, chirp );
-        silk_bwexpander_FLP( coefs_ana, order, chirp );
+        silk_bwexpander_FLP( coefs, order, chirp );
 
         /* Convert to monic warped coefficients */
         for( i = order - 1; i > 0; i-- ) {
-            coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
-            coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
+            coefs[ i - 1 ] -= lambda * coefs[ i ];
         }
-        gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
-        gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
+        gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
         for( i = 0; i < order; i++ ) {
-            coefs_syn[ i ] *= gain_syn;
-            coefs_ana[ i ] *= gain_ana;
+            coefs[ i ] *= gain;
         }
     }
     silk_assert( 0 );
 }
 
+static OPUS_INLINE void limit_coefs(
+    silk_float           *coefs,
+    silk_float           limit,
+    opus_int             order
+) {
+    opus_int   i, iter, ind = 0;
+    silk_float tmp, maxabs, chirp;
+
+    for( iter = 0; iter < 10; iter++ ) {
+        /* Find maximum absolute value */
+        maxabs = -1.0f;
+        for( i = 0; i < order; i++ ) {
+            tmp = silk_abs_float( coefs[ i ] );
+            if( tmp > maxabs ) {
+                maxabs = tmp;
+                ind = i;
+            }
+        }
+        if( maxabs <= limit ) {
+            /* Coefficients are within range - done */
+            return;
+        }
+
+        /* Apply bandwidth expansion */
+        chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
+        silk_bwexpander_FLP( coefs, order, chirp );
+    }
+    silk_assert( 0 );
+}
+
 /* Compute noise shaping coefficients and initial gain values */
 void silk_noise_shape_analysis_FLP(
     silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
@@ -133,12 +152,13 @@
 )
 {
     silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
-    opus_int     k, nSamples;
-    silk_float   SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt;
-    silk_float   nrg, pre_nrg, log_energy, log_energy_prev, energy_variation;
-    silk_float   delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping;
+    opus_int     k, nSamples, nSegs;
+    silk_float   SNR_adj_dB, HarmShapeGain, Tilt;
+    silk_float   nrg, log_energy, log_energy_prev, energy_variation;
+    silk_float   BWExp, gain_mult, gain_add, strength, b, warping;
     silk_float   x_windowed[ SHAPE_LPC_WIN_MAX ];
     silk_float   auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
+    silk_float   rc[ MAX_SHAPE_LPC_ORDER + 1 ];
     const silk_float *x_ptr, *pitch_res_ptr;
 
     /* Point to start of first LPC analysis block */
@@ -176,14 +196,14 @@
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
         /* Initially set to 0; may be overruled in process_gains(..) */
         psEnc->sCmn.indices.quantOffsetType = 0;
-        psEncCtrl->sparseness = 0.0f;
     } else {
         /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
         nSamples = 2 * psEnc->sCmn.fs_kHz;
         energy_variation = 0.0f;
         log_energy_prev  = 0.0f;
         pitch_res_ptr = pitch_res;
-        for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
+        nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
+        for( k = 0; k < nSegs; k++ ) {
             nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );
             log_energy = silk_log2( nrg );
             if( k > 0 ) {
@@ -192,17 +212,13 @@
             log_energy_prev = log_energy;
             pitch_res_ptr += nSamples;
         }
-        psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) );
 
         /* Set quantization offset depending on sparseness measure */
-        if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) {
+        if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) {
             psEnc->sCmn.indices.quantOffsetType = 0;
         } else {
             psEnc->sCmn.indices.quantOffsetType = 1;
         }
-
-        /* Increase coding SNR for sparse signals */
-        SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f );
     }
 
     /*******************************/
@@ -210,19 +226,10 @@
     /*******************************/
     /* More BWE for signals with high prediction gain */
     strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain;           /* between 0.0 and 1.0 */
-    BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
-    delta  = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality );
-    BWExp1 -= delta;
-    BWExp2 += delta;
-    /* BWExp1 will be applied after BWExp2, so make it relative */
-    BWExp1 /= BWExp2;
+    BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
 
-    if( psEnc->sCmn.warping_Q16 > 0 ) {
-        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
-        warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
-    } else {
-        warping = 0.0f;
-    }
+    /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
+    warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
 
     /********************************************/
     /* Compute noise shaping AR coefs and gains */
@@ -252,37 +259,28 @@
         }
 
         /* Add white noise, as a fraction of energy */
-        auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION;
+        auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f;
 
         /* Convert correlations to prediction coefficients, and compute residual energy */
-        nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder );
+        nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder );
+        silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder );
         psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );
 
         if( psEnc->sCmn.warping_Q16 > 0 ) {
             /* Adjust gain for warping */
-            psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
+            psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
         }
 
         /* Bandwidth expansion for synthesis filter shaping */
-        silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 );
+        silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp );
 
-        /* Compute noise shaping filter coefficients */
-        silk_memcpy(
-            &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
-            &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ],
-            psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) );
-
-        /* Bandwidth expansion for analysis filter shaping */
-        silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
-
-        /* Ratio of prediction gains, in energy domain */
-        pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
-        nrg     = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
-        psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
-
-        /* Convert to monic warped prediction coefficients and limit absolute values */
-        warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
-            warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
+        if( psEnc->sCmn.warping_Q16 > 0 ) {
+            /* Convert to monic warped prediction coefficients and limit absolute values */
+            warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
+        } else {
+            /* Limit absolute values */
+            limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder );
+        }
     }
 
     /*****************/
@@ -296,11 +294,6 @@
         psEncCtrl->Gains[ k ] += gain_add;
     }
 
-    gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT;
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
-        psEncCtrl->GainsPre[ k ] *= gain_mult;
-    }
-
     /************************************************/
     /* Control low-frequency shaping and noise tilt */
     /************************************************/
@@ -331,12 +324,6 @@
     /****************************/
     /* HARMONIC SHAPING CONTROL */
     /****************************/
-    /* Control boosting of harmonic frequencies */
-    HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr;
-
-    /* More harmonic boost for noisy input signals */
-    HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality );
-
     if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
         /* Harmonic noise shaping */
         HarmShapeGain = HARMONIC_SHAPING;
@@ -355,8 +342,6 @@
     /* Smooth over subframes */
     /*************************/
     for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
-        psShapeSt->HarmBoost_smth     += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth );
-        psEncCtrl->HarmBoost[ k ]      = psShapeSt->HarmBoost_smth;
         psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
         psEncCtrl->HarmShapeGain[ k ]  = psShapeSt->HarmShapeGain_smth;
         psShapeSt->Tilt_smth          += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
diff --git a/silk/float/pitch_analysis_core_FLP.c b/silk/float/pitch_analysis_core_FLP.c
index d0e637a..b371693 100644
--- a/silk/float/pitch_analysis_core_FLP.c
+++ b/silk/float/pitch_analysis_core_FLP.c
@@ -159,7 +159,7 @@
 
     /* Low-pass filter */
     for( i = frame_length_4kHz - 1; i > 0; i-- ) {
-        frame_4kHz[ i ] += frame_4kHz[ i - 1 ];
+        frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
     }
 
     /******************************************************************************
diff --git a/silk/float/prefilter_FLP.c b/silk/float/prefilter_FLP.c
deleted file mode 100644
index 8bc32fb..0000000
--- a/silk/float/prefilter_FLP.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/***********************************************************************
-Copyright (c) 2006-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "main_FLP.h"
-#include "tuning_parameters.h"
-
-/*
-* Prefilter for finding Quantizer input signal
-*/
-static OPUS_INLINE void silk_prefilt_FLP(
-    silk_prefilter_state_FLP    *P,                 /* I/O state */
-    silk_float                  st_res[],           /* I */
-    silk_float                  xw[],               /* O */
-    silk_float                  *HarmShapeFIR,      /* I */
-    silk_float                  Tilt,               /* I */
-    silk_float                  LF_MA_shp,          /* I */
-    silk_float                  LF_AR_shp,          /* I */
-    opus_int                    lag,                /* I */
-    opus_int                    length              /* I */
-);
-
-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]                    */
-    const silk_float                 input[],            /* I    Input signal [length]                   */
-    const silk_float                 lambda,             /* I    Warping factor                          */
-    const opus_int                   length,             /* I    Length of input signal                  */
-    const opus_int                   order               /* I    Filter order (even)                     */
-)
-{
-    opus_int     n, i;
-    silk_float   acc, tmp1, tmp2;
-
-    /* Order must be even */
-    silk_assert( ( order & 1 ) == 0 );
-
-    for( n = 0; n < length; n++ ) {
-        /* Output of lowpass section */
-        tmp2 = state[ 0 ] + lambda * state[ 1 ];
-        state[ 0 ] = input[ n ];
-        /* Output of allpass section */
-        tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );
-        state[ 1 ] = tmp2;
-        acc = coef[ 0 ] * tmp2;
-        /* Loop over allpass sections */
-        for( i = 2; i < order; i += 2 ) {
-            /* Output of allpass section */
-            tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );
-            state[ i ] = tmp1;
-            acc += coef[ i - 1 ] * tmp1;
-            /* Output of allpass section */
-            tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );
-            state[ i + 1 ] = tmp2;
-            acc += coef[ i ] * tmp2;
-        }
-        state[ order ] = tmp1;
-        acc += coef[ order - 1 ] * tmp1;
-        res[ n ] = input[ n ] - acc;
-    }
-}
-
-/*
-* silk_prefilter. Main prefilter function
-*/
-void silk_prefilter_FLP(
-    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
-    const silk_encoder_control_FLP  *psEncCtrl,                         /* I    Encoder control FLP                         */
-    silk_float                      xw[],                               /* O    Weighted signal                             */
-    const silk_float                x[]                                 /* I    Speech signal                               */
-)
-{
-    silk_prefilter_state_FLP *P = &psEnc->sPrefilt;
-    opus_int   j, k, lag;
-    silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp;
-    silk_float B[ 2 ];
-    const silk_float *AR1_shp;
-    const silk_float *px;
-    silk_float *pxw;
-    silk_float HarmShapeFIR[ 3 ];
-    silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
-
-    /* Set up pointers */
-    px  = x;
-    pxw = xw;
-    lag = P->lagPrev;
-    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
-        /* Update Variables that change per sub frame */
-        if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
-            lag = psEncCtrl->pitchL[ k ];
-        }
-
-        /* Noise shape parameters */
-        HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] );
-        HarmShapeFIR[ 0 ] = 0.25f               * HarmShapeGain;
-        HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain;
-        HarmShapeFIR[ 2 ] = 0.25f               * HarmShapeGain;
-        Tilt      =  psEncCtrl->Tilt[ k ];
-        LF_MA_shp =  psEncCtrl->LF_MA_shp[ k ];
-        LF_AR_shp =  psEncCtrl->LF_AR_shp[ k ];
-        AR1_shp   = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ];
-
-        /* Short term FIR filtering */
-        silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px,
-            (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
-
-        /* Reduce (mainly) low frequencies during harmonic emphasis */
-        B[ 0 ] =  psEncCtrl->GainsPre[ k ];
-        B[ 1 ] = -psEncCtrl->GainsPre[ k ] *
-            ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT );
-        pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP;
-        for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
-            pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ];
-        }
-        P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
-
-        silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length );
-
-        px  += psEnc->sCmn.subfr_length;
-        pxw += psEnc->sCmn.subfr_length;
-    }
-    P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
-}
-
-/*
-* Prefilter for finding Quantizer input signal
-*/
-static OPUS_INLINE void silk_prefilt_FLP(
-    silk_prefilter_state_FLP    *P,                 /* I/O state */
-    silk_float                  st_res[],           /* I */
-    silk_float                  xw[],               /* O */
-    silk_float                  *HarmShapeFIR,      /* I */
-    silk_float                  Tilt,               /* I */
-    silk_float                  LF_MA_shp,          /* I */
-    silk_float                  LF_AR_shp,          /* I */
-    opus_int                    lag,                /* I */
-    opus_int                    length              /* I */
-)
-{
-    opus_int   i;
-    opus_int   idx, LTP_shp_buf_idx;
-    silk_float n_Tilt, n_LF, n_LTP;
-    silk_float sLF_AR_shp, sLF_MA_shp;
-    silk_float *LTP_shp_buf;
-
-    /* To speed up use temp variables instead of using the struct */
-    LTP_shp_buf     = P->sLTP_shp;
-    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
-    sLF_AR_shp      = P->sLF_AR_shp;
-    sLF_MA_shp      = P->sLF_MA_shp;
-
-    for( i = 0; i < length; i++ ) {
-        if( lag > 0 ) {
-            silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
-            idx = lag + LTP_shp_buf_idx;
-            n_LTP  = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];
-            n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ] * HarmShapeFIR[ 1 ];
-            n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];
-        } else {
-            n_LTP = 0;
-        }
-
-        n_Tilt = sLF_AR_shp * Tilt;
-        n_LF   = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;
-
-        sLF_AR_shp = st_res[ i ] - n_Tilt;
-        sLF_MA_shp = sLF_AR_shp - n_LF;
-
-        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
-        LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;
-
-        xw[ i ] = sLF_MA_shp - n_LTP;
-    }
-    /* Copy temp variable back to state */
-    P->sLF_AR_shp       = sLF_AR_shp;
-    P->sLF_MA_shp       = sLF_MA_shp;
-    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
-}
diff --git a/silk/float/schur_FLP.c b/silk/float/schur_FLP.c
index ee436f8..c1e0bbb 100644
--- a/silk/float/schur_FLP.c
+++ b/silk/float/schur_FLP.c
@@ -38,22 +38,23 @@
 )
 {
     opus_int   k, n;
-    silk_float C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
-    silk_float Ctmp1, Ctmp2, rc_tmp;
+    double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
+    double Ctmp1, Ctmp2, rc_tmp;
 
-    silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
+    silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
 
     /* Copy correlations */
-    for( k = 0; k < order+1; k++ ) {
+    k = 0;
+    do {
         C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ];
-    }
+    } while( ++k <= order );
 
     for( k = 0; k < order; k++ ) {
         /* Get reflection coefficient */
         rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f );
 
         /* Save the output */
-        refl_coef[ k ] = rc_tmp;
+        refl_coef[ k ] = (silk_float)rc_tmp;
 
         /* Update correlations */
         for( n = 0; n < order - k; n++ ) {
@@ -65,6 +66,5 @@
     }
 
     /* Return residual energy */
-    return C[ 0 ][ 1 ];
+    return (silk_float)C[ 0 ][ 1 ];
 }
-
diff --git a/silk/float/solve_LS_FLP.c b/silk/float/solve_LS_FLP.c
deleted file mode 100644
index 7c90d66..0000000
--- a/silk/float/solve_LS_FLP.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/***********************************************************************
-Copyright (c) 2006-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.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "main_FLP.h"
-#include "tuning_parameters.h"
-
-/**********************************************************************
- * LDL Factorisation. Finds the upper triangular matrix L and the diagonal
- * Matrix D (only the diagonal elements returned in a vector)such that
- * the symmetric matric A is given by A = L*D*L'.
- **********************************************************************/
-static OPUS_INLINE void silk_LDL_FLP(
-    silk_float          *A,         /* I/O  Pointer to Symetric Square Matrix                               */
-    opus_int            M,          /* I    Size of Matrix                                                  */
-    silk_float          *L,         /* I/O  Pointer to Square Upper triangular Matrix                       */
-    silk_float          *Dinv       /* I/O  Pointer to vector holding the inverse diagonal elements of D    */
-);
-
-/**********************************************************************
- * Function to solve linear equation Ax = b, when A is a MxM lower
- * triangular matrix, with ones on the diagonal.
- **********************************************************************/
-static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
-    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */
-    opus_int            M,          /* I    Dim of Matrix equation                                          */
-    const silk_float    *b,         /* I    b Vector                                                        */
-    silk_float          *x          /* O    x Vector                                                        */
-);
-
-/**********************************************************************
- * Function to solve linear equation (A^T)x = b, when A is a MxM lower
- * triangular, with ones on the diagonal. (ie then A^T is upper triangular)
- **********************************************************************/
-static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
-    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */
-    opus_int            M,          /* I    Dim of Matrix equation                                          */
-    const silk_float    *b,         /* I    b Vector                                                        */
-    silk_float          *x          /* O    x Vector                                                        */
-);
-
-/**********************************************************************
- * Function to solve linear equation Ax = b, when A is a MxM
- * symmetric square matrix - using LDL factorisation
- **********************************************************************/
-void silk_solve_LDL_FLP(
-    silk_float                      *A,                                 /* I/O  Symmetric square matrix, out: reg.          */
-    const opus_int                  M,                                  /* I    Size of matrix                              */
-    const silk_float                *b,                                 /* I    Pointer to b vector                         */
-    silk_float                      *x                                  /* O    Pointer to x solution vector                */
-)
-{
-    opus_int   i;
-    silk_float L[    MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ];
-    silk_float T[    MAX_MATRIX_SIZE ];
-    silk_float Dinv[ MAX_MATRIX_SIZE ]; /* inverse diagonal elements of D*/
-
-    silk_assert( M <= MAX_MATRIX_SIZE );
-
-    /***************************************************
-    Factorize A by LDL such that A = L*D*(L^T),
-    where L is lower triangular with ones on diagonal
-    ****************************************************/
-    silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv );
-
-    /****************************************************
-    * substitute D*(L^T) = T. ie:
-    L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b
-    ******************************************************/
-    silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T );
-
-    /****************************************************
-    D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is
-    diagonal just multiply with 1/d_i
-    ****************************************************/
-    for( i = 0; i < M; i++ ) {
-        T[ i ] = T[ i ] * Dinv[ i ];
-    }
-    /****************************************************
-    x = inv(L') * inv(D) * T
-    *****************************************************/
-    silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x );
-}
-
-static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
-    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */
-    opus_int            M,          /* I    Dim of Matrix equation                                          */
-    const silk_float    *b,         /* I    b Vector                                                        */
-    silk_float          *x          /* O    x Vector                                                        */
-)
-{
-    opus_int   i, j;
-    silk_float temp;
-    const silk_float *ptr1;
-
-    for( i = M - 1; i >= 0; i-- ) {
-        ptr1 =  matrix_adr( L, 0, i, M );
-        temp = 0;
-        for( j = M - 1; j > i ; j-- ) {
-            temp += ptr1[ j * M ] * x[ j ];
-        }
-        temp = b[ i ] - temp;
-        x[ i ] = temp;
-    }
-}
-
-static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
-    const silk_float    *L,         /* I    Pointer to Lower Triangular Matrix                              */
-    opus_int            M,          /* I    Dim of Matrix equation                                          */
-    const silk_float    *b,         /* I    b Vector                                                        */
-    silk_float          *x          /* O    x Vector                                                        */
-)
-{
-    opus_int   i, j;
-    silk_float temp;
-    const silk_float *ptr1;
-
-    for( i = 0; i < M; i++ ) {
-        ptr1 =  matrix_adr( L, i, 0, M );
-        temp = 0;
-        for( j = 0; j < i; j++ ) {
-            temp += ptr1[ j ] * x[ j ];
-        }
-        temp = b[ i ] - temp;
-        x[ i ] = temp;
-    }
-}
-
-static OPUS_INLINE void silk_LDL_FLP(
-    silk_float          *A,         /* I/O  Pointer to Symetric Square Matrix                               */
-    opus_int            M,          /* I    Size of Matrix                                                  */
-    silk_float          *L,         /* I/O  Pointer to Square Upper triangular Matrix                       */
-    silk_float          *Dinv       /* I/O  Pointer to vector holding the inverse diagonal elements of D    */
-)
-{
-    opus_int i, j, k, loop_count, err = 1;
-    silk_float *ptr1, *ptr2;
-    double temp, diag_min_value;
-    silk_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; /* temp arrays*/
-
-    silk_assert( M <= MAX_MATRIX_SIZE );
-
-    diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] );
-    for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) {
-        err = 0;
-        for( j = 0; j < M; j++ ) {
-            ptr1 = matrix_adr( L, j, 0, M );
-            temp = matrix_ptr( A, j, j, M ); /* element in row j column j*/
-            for( i = 0; i < j; i++ ) {
-                v[ i ] = ptr1[ i ] * D[ i ];
-                temp  -= ptr1[ i ] * v[ i ];
-            }
-            if( temp < diag_min_value ) {
-                /* Badly conditioned matrix: add white noise and run again */
-                temp = ( loop_count + 1 ) * diag_min_value - temp;
-                for( i = 0; i < M; i++ ) {
-                    matrix_ptr( A, i, i, M ) += ( silk_float )temp;
-                }
-                err = 1;
-                break;
-            }
-            D[ j ]    = ( silk_float )temp;
-            Dinv[ j ] = ( silk_float )( 1.0f / temp );
-            matrix_ptr( L, j, j, M ) = 1.0f;
-
-            ptr1 = matrix_adr( A, j, 0, M );
-            ptr2 = matrix_adr( L, j + 1, 0, M);
-            for( i = j + 1; i < M; i++ ) {
-                temp = 0.0;
-                for( k = 0; k < j; k++ ) {
-                    temp += ptr2[ k ] * v[ k ];
-                }
-                matrix_ptr( L, i, j, M ) = ( silk_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] );
-                ptr2 += M; /* go to next column*/
-            }
-        }
-    }
-    silk_assert( err == 0 );
-}
-
diff --git a/silk/float/structs_FLP.h b/silk/float/structs_FLP.h
index 14d647c..3150b38 100644
--- a/silk/float/structs_FLP.h
+++ b/silk/float/structs_FLP.h
@@ -42,32 +42,16 @@
 /********************************/
 typedef struct {
     opus_int8                   LastGainIndex;
-    silk_float                  HarmBoost_smth;
     silk_float                  HarmShapeGain_smth;
     silk_float                  Tilt_smth;
 } silk_shape_state_FLP;
 
 /********************************/
-/* Prefilter state              */
-/********************************/
-typedef struct {
-    silk_float                  sLTP_shp[ LTP_BUF_LENGTH ];
-    silk_float                  sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];
-    opus_int                    sLTP_shp_buf_idx;
-    silk_float                  sLF_AR_shp;
-    silk_float                  sLF_MA_shp;
-    silk_float                  sHarmHP;
-    opus_int32                  rand_seed;
-    opus_int                    lagPrev;
-} silk_prefilter_state_FLP;
-
-/********************************/
 /* Encoder state FLP            */
 /********************************/
 typedef struct {
     silk_encoder_state          sCmn;                               /* Common struct, shared with fixed-point code */
     silk_shape_state_FLP        sShape;                             /* Noise shaping state */
-    silk_prefilter_state_FLP    sPrefilt;                           /* Prefilter State */
 
     /* Buffer for find pitch and noise shape analysis */
     silk_float                  x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
@@ -86,12 +70,9 @@
     opus_int                    pitchL[ MAX_NB_SUBFR ];
 
     /* Noise shaping parameters */
-    silk_float                  AR1[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
-    silk_float                  AR2[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+    silk_float                  AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
     silk_float                  LF_MA_shp[     MAX_NB_SUBFR ];
     silk_float                  LF_AR_shp[     MAX_NB_SUBFR ];
-    silk_float                  GainsPre[      MAX_NB_SUBFR ];
-    silk_float                  HarmBoost[     MAX_NB_SUBFR ];
     silk_float                  Tilt[          MAX_NB_SUBFR ];
     silk_float                  HarmShapeGain[ MAX_NB_SUBFR ];
     silk_float                  Lambda;
@@ -99,7 +80,6 @@
     silk_float                  coding_quality;
 
     /* Measures */
-    silk_float                  sparseness;
     silk_float                  predGain;
     silk_float                  LTPredCodGain;
     silk_float                  ResNrg[ MAX_NB_SUBFR ];             /* Residual energy per subframe */
diff --git a/silk/float/wrappers_FLP.c b/silk/float/wrappers_FLP.c
index 6666b8e..ad90b87 100644
--- a/silk/float/wrappers_FLP.c
+++ b/silk/float/wrappers_FLP.c
@@ -54,13 +54,14 @@
 void silk_NLSF2A_FLP(
     silk_float                      *pAR,                               /* O    LPC coefficients [ LPC_order ]              */
     const opus_int16                *NLSF_Q15,                          /* I    NLSF vector      [ LPC_order ]              */
-    const opus_int                  LPC_order                           /* I    LPC order                                   */
+    const opus_int                  LPC_order,                          /* I    LPC order                                   */
+    int                             arch                                /* I    Run-time architecture                       */
 )
 {
     opus_int   i;
     opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];
 
-    silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order );
+    silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch );
 
     for( i = 0; i < LPC_order; i++ ) {
         pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
@@ -102,14 +103,14 @@
 )
 {
     opus_int     i, j;
-    opus_int32   x_Q3[ MAX_FRAME_LENGTH ];
+    opus_int16   x16[ MAX_FRAME_LENGTH ];
     opus_int32   Gains_Q16[ MAX_NB_SUBFR ];
     silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
     opus_int16   LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
     opus_int     LTP_scale_Q14;
 
     /* Noise shaping parameters */
-    opus_int16   AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+    opus_int16   AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
     opus_int32   LF_shp_Q14[ MAX_NB_SUBFR ];         /* Packs two int16 coefficients per int32 value             */
     opus_int     Lambda_Q10;
     opus_int     Tilt_Q14[ MAX_NB_SUBFR ];
@@ -119,7 +120,7 @@
     /* Noise shape parameters */
     for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
         for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) {
-            AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
+            AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
         }
     }
 
@@ -155,16 +156,16 @@
 
     /* Convert input to fix */
     for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
-        x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] );
+        x16[ i ] = silk_float2int( x[ i ] );
     }
 
     /* Call NSQ */
     if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
-        silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
-            AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
+        silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
+            AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
     } else {
-        silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
-            AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
+        silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
+            AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
     }
 }
 
@@ -172,31 +173,35 @@
 /* Floating-point Silk LTP quantiation wrapper */
 /***********************************************/
 void silk_quant_LTP_gains_FLP(
-    silk_float                      B[ MAX_NB_SUBFR * LTP_ORDER ],      /* I/O  (Un-)quantized LTP gains                    */
+    silk_float                      B[ MAX_NB_SUBFR * LTP_ORDER ],      /* O    Quantized LTP gains                            */
     opus_int8                       cbk_index[ MAX_NB_SUBFR ],          /* O    Codebook index                              */
     opus_int8                       *periodicity_index,                 /* O    Periodicity index                           */
     opus_int32                      *sum_log_gain_Q7,                   /* I/O  Cumulative max prediction gain  */
-    const silk_float                W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I    Error weights                        */
-    const opus_int                  mu_Q10,                             /* I    Mu value (R/D tradeoff)                     */
-    const opus_int                  lowComplexity,                      /* I    Flag for low complexity                     */
-    const opus_int                  nb_subfr,                           /* I    number of subframes                         */
+    silk_float                      *pred_gain_dB,                        /* O    LTP prediction gain                            */
+    const silk_float                XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I    Correlation matrix                    */
+    const silk_float                xX[ MAX_NB_SUBFR * LTP_ORDER ],        /* I    Correlation vector                            */
+    const opus_int                    subfr_len,                            /* I    Number of samples per subframe                */
+    const opus_int                    nb_subfr,                           /* I    Number of subframes                            */
     int                             arch                                /* I    Run-time architecture                       */
 )
 {
-    opus_int   i;
+    opus_int   i, pred_gain_dB_Q7;
     opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ];
-    opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ];
+    opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
+    opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ];
 
-    for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
-        B_Q14[ i ] = (opus_int16)silk_float2int( B[ i ] * 16384.0f );
-    }
     for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {
-        W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f );
+        XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f );
+    }
+    for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
+        xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f );
     }
 
-    silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, W_Q18, mu_Q10, lowComplexity, nb_subfr, arch );
+    silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch );
 
     for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
         B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f );
     }
+
+    *pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f );
 }
diff --git a/silk/gain_quant.c b/silk/gain_quant.c
index 64ccd06..ee65245 100644
--- a/silk/gain_quant.c
+++ b/silk/gain_quant.c
@@ -76,6 +76,7 @@
             /* Accumulate deltas */
             if( ind[ k ] > double_step_size_threshold ) {
                 *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;
+                *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 );
             } else {
                 *prev_ind += ind[ k ];
             }
diff --git a/silk/init_decoder.c b/silk/init_decoder.c
index f887c67..16c03dc 100644
--- a/silk/init_decoder.c
+++ b/silk/init_decoder.c
@@ -44,6 +44,7 @@
     /* Used to deactivate LSF interpolation */
     psDec->first_frame_after_reset = 1;
     psDec->prev_gain_Q16 = 65536;
+    psDec->arch = opus_select_arch();
 
     /* Reset CNG state */
     silk_CNG_Reset( psDec );
diff --git a/silk/lin2log.c b/silk/lin2log.c
index d4fe515..0d5155a 100644
--- a/silk/lin2log.c
+++ b/silk/lin2log.c
@@ -41,6 +41,6 @@
     silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );
 
     /* Piece-wise parabolic approximation */
-    return silk_LSHIFT( 31 - lz, 7 ) + silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 );
+    return silk_ADD_LSHIFT32( silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ), 31 - lz, 7 );
 }
 
diff --git a/silk/macros.h b/silk/macros.h
index d3ca347..3c67b6e 100644
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -36,14 +36,6 @@
 #include "opus_defines.h"
 #include "arch.h"
 
-#if OPUS_GNUC_PREREQ(3, 0)
-#define opus_likely(x)       (__builtin_expect(!!(x), 1))
-#define opus_unlikely(x)     (__builtin_expect(!!(x), 0))
-#else
-#define opus_likely(x)       (!!(x))
-#define opus_unlikely(x)     (!!(x))
-#endif
-
 /* This is an OPUS_INLINE header file for general platform. */
 
 /* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
diff --git a/silk/main.h b/silk/main.h
index 2f90d68..1a33eed 100644
--- a/silk/main.h
+++ b/silk/main.h
@@ -42,6 +42,10 @@
 #include "x86/main_sse.h"
 #endif
 
+#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
+#include "arm/NSQ_del_dec_arm.h"
+#endif
+
 /* Convert Left/Right stereo signal to adaptive Mid/Side representation */
 void silk_stereo_LR_to_MS(
     stereo_enc_state            *state,                         /* I/O  State                                       */
@@ -109,22 +113,22 @@
 
 /* Encodes signs of excitation */
 void silk_encode_signs(
-    ec_enc                      *psRangeEnc,                        /* I/O  Compressor data structure                   */
-    const opus_int8             pulses[],                           /* I    pulse signal                                */
-    opus_int                    length,                             /* I    length of input                             */
-    const opus_int              signalType,                         /* I    Signal type                                 */
-    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */
-    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */
+    ec_enc                      *psRangeEnc,                        /* I/O  Compressor data structure               */
+    const opus_int8             pulses[],                           /* I    pulse signal                            */
+    opus_int                    length,                             /* I    length of input                         */
+    const opus_int              signalType,                         /* I    Signal type                             */
+    const opus_int              quantOffsetType,                    /* I    Quantization offset type                */
+    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block        */
 );
 
 /* Decodes signs of excitation */
 void silk_decode_signs(
-    ec_dec                      *psRangeDec,                        /* I/O  Compressor data structure                   */
-    opus_int16                  pulses[],                           /* I/O  pulse signal                                */
-    opus_int                    length,                             /* I    length of input                             */
-    const opus_int              signalType,                         /* I    Signal type                                 */
-    const opus_int              quantOffsetType,                    /* I    Quantization offset type                    */
-    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */
+    ec_dec                      *psRangeDec,                        /* I/O  Compressor data structure               */
+    opus_int16                  pulses[],                           /* I/O  pulse signal                            */
+    opus_int                    length,                             /* I    length of input                         */
+    const opus_int              signalType,                         /* I    Signal type                             */
+    const opus_int              quantOffsetType,                    /* I    Quantization offset type                */
+    const opus_int              sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block        */
 );
 
 /* Check encoder control struct */
@@ -205,37 +209,37 @@
 
 /* LTP tap quantizer */
 void silk_quant_LTP_gains(
-    opus_int16                  B_Q14[ MAX_NB_SUBFR * LTP_ORDER ],          /* I/O  (un)quantized LTP gains         */
+    opus_int16                  B_Q14[ MAX_NB_SUBFR * LTP_ORDER ],          /* O    Quantized LTP gains             */
     opus_int8                   cbk_index[ MAX_NB_SUBFR ],                  /* O    Codebook Index                  */
     opus_int8                   *periodicity_index,                         /* O    Periodicity Index               */
     opus_int32                  *sum_gain_dB_Q7,                            /* I/O  Cumulative max prediction gain  */
-    const opus_int32            W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ],  /* I    Error Weights in Q18            */
-    opus_int                    mu_Q9,                                      /* I    Mu value (R/D tradeoff)         */
-    opus_int                    lowComplexity,                              /* I    Flag for low complexity         */
-    const opus_int              nb_subfr,                                   /* I    number of subframes             */
+    opus_int                    *pred_gain_dB_Q7,                           /* O    LTP prediction gain             */
+    const opus_int32            XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I    Correlation matrix in Q18       */
+    const opus_int32            xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ],           /* I    Correlation vector in Q18       */
+    const opus_int              subfr_len,                                  /* I    Number of samples per subframe  */
+    const opus_int              nb_subfr,                                   /* I    Number of subframes             */
     int                         arch                                        /* I    Run-time architecture           */
 );
 
 /* Entropy constrained matrix-weighted VQ, for a single input data vector */
 void silk_VQ_WMat_EC_c(
     opus_int8                   *ind,                           /* O    index of best codebook vector               */
-    opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */
+    opus_int32                  *res_nrg_Q15,                   /* O    best residual energy                        */
+    opus_int32                  *rate_dist_Q8,                  /* O    best total bitrate                          */
     opus_int                    *gain_Q7,                       /* O    sum of absolute LTP coefficients            */
-    const opus_int16            *in_Q14,                        /* I    input vector to be quantized                */
-    const opus_int32            *W_Q18,                         /* I    weighting matrix                            */
+    const opus_int32            *XX_Q17,                        /* I    correlation matrix                          */
+    const opus_int32            *xX_Q17,                        /* I    correlation vector                          */
     const opus_int8             *cb_Q7,                         /* I    codebook                                    */
     const opus_uint8            *cb_gain_Q7,                    /* I    codebook effective gain                     */
     const opus_uint8            *cl_Q5,                         /* I    code length for each codebook vector        */
-    const opus_int              mu_Q9,                          /* I    tradeoff betw. weighted error and rate      */
+    const opus_int              subfr_len,                      /* I    number of samples per subframe              */
     const opus_int32            max_gain_Q7,                    /* I    maximum sum of absolute LTP coefficients    */
-    opus_int                    L                               /* I    number of vectors in codebook               */
+    const opus_int              L                               /* I    number of vectors in codebook               */
 );
 
 #if !defined(OVERRIDE_silk_VQ_WMat_EC)
-#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
-                          mu_Q9, max_gain_Q7, L, arch) \
-    ((void)(arch),silk_VQ_WMat_EC_c(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
-                          mu_Q9, max_gain_Q7, L))
+#define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L, arch) \
+    ((void)(arch),silk_VQ_WMat_EC_c(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L))
 #endif
 
 /************************************/
@@ -243,14 +247,14 @@
 /************************************/
 
 void silk_NSQ_c(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
-    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
+    const opus_int16            x16[],                                      /* I    Input                           */
     opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */
     const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */
     const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */
-    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */
+    const opus_int16            AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I  Noise shaping coefs             */
     const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */
     const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */
     const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */
@@ -261,22 +265,22 @@
 );
 
 #if !defined(OVERRIDE_silk_NSQ)
-#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
+#define silk_NSQ(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
                    HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
-    ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
+    ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
                    HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
 #endif
 
 /* Noise shaping using delayed decision */
 void silk_NSQ_del_dec_c(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
-    const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
+    const opus_int16            x16[],                                      /* I    Input                           */
     opus_int8                   pulses[],                                   /* O    Quantized pulse signal          */
     const opus_int16            PredCoef_Q12[ 2 * MAX_LPC_ORDER ],          /* I    Short term prediction coefs     */
     const opus_int16            LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],    /* I    Long term prediction coefs      */
-    const opus_int16            AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs             */
+    const opus_int16            AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I  Noise shaping coefs             */
     const opus_int              HarmShapeGain_Q14[ MAX_NB_SUBFR ],          /* I    Long term shaping coefs         */
     const opus_int              Tilt_Q14[ MAX_NB_SUBFR ],                   /* I    Spectral tilt                   */
     const opus_int32            LF_shp_Q14[ MAX_NB_SUBFR ],                 /* I    Low frequency shaping coefs     */
@@ -287,9 +291,9 @@
 );
 
 #if !defined(OVERRIDE_silk_NSQ_del_dec)
-#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
+#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
                            HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
-    ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
+    ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
                            HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
 #endif
 
@@ -346,6 +350,7 @@
     opus_int32                  err_Q26[],                      /* O    Quantization errors [K]                     */
     const opus_int16            in_Q15[],                       /* I    Input vectors to be quantized [LPC_order]   */
     const opus_uint8            pCB_Q8[],                       /* I    Codebook vectors [K*LPC_order]              */
+    const opus_int16            pWght_Q9[],                     /* I    Codebook weights [K*LPC_order]              */
     const opus_int              K,                              /* I    Number of codebook vectors                  */
     const opus_int              LPC_order                       /* I    Number of LPCs                              */
 );
diff --git a/silk/mips/NSQ_del_dec_mipsr1.h b/silk/mips/NSQ_del_dec_mipsr1.h
index ad1cfe2..cd70713 100644
--- a/silk/mips/NSQ_del_dec_mipsr1.h
+++ b/silk/mips/NSQ_del_dec_mipsr1.h
@@ -61,7 +61,7 @@
     opus_int            predictLPCOrder,        /* I    Prediction filter order             */
     opus_int            warping_Q16,            /* I                                        */
     opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
-    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
     opus_int            decisionDelay,          /* I                                        */
     int                 arch                    /* I                                        */
 )
@@ -323,8 +323,9 @@
             psSS[ 1 ].xq_Q14       = xq_Q14;
         }
 
-        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */
-        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */
+        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
+        if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
+        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
 
         /* Find winner */
         RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
diff --git a/silk/mips/sigproc_fix_mipsr1.h b/silk/mips/sigproc_fix_mipsr1.h
index 3b0a695..51520c0 100644
--- a/silk/mips/sigproc_fix_mipsr1.h
+++ b/silk/mips/sigproc_fix_mipsr1.h
@@ -28,11 +28,6 @@
 #ifndef SILK_SIGPROC_FIX_MIPSR1_H
 #define SILK_SIGPROC_FIX_MIPSR1_H
 
-#ifdef  __cplusplus
-extern "C"
-{
-#endif
-
 #undef silk_SAT16
 static inline short int silk_SAT16(int a)
 {
diff --git a/silk/process_NLSFs.c b/silk/process_NLSFs.c
index 0ab71f0..2f10f8d 100644
--- a/silk/process_NLSFs.c
+++ b/silk/process_NLSFs.c
@@ -89,7 +89,7 @@
         NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
 
     /* Convert quantized NLSFs back to LPC coefficients */
-    silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder );
+    silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch );
 
     if( doInterpolate ) {
         /* Calculate the interpolated, quantized LSF vector for the first half */
@@ -97,7 +97,7 @@
             psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
 
         /* Convert back to LPC coefficients */
-        silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder );
+        silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch );
 
     } else {
         /* Copy LPC coefficients for first half from second half */
diff --git a/silk/quant_LTP_gains.c b/silk/quant_LTP_gains.c
index 513a8c4..d6b8eff 100644
--- a/silk/quant_LTP_gains.c
+++ b/silk/quant_LTP_gains.c
@@ -33,14 +33,15 @@
 #include "tuning_parameters.h"
 
 void silk_quant_LTP_gains(
-    opus_int16                  B_Q14[ MAX_NB_SUBFR * LTP_ORDER ],          /* I/O  (un)quantized LTP gains         */
+    opus_int16                  B_Q14[ MAX_NB_SUBFR * LTP_ORDER ],          /* O    Quantized LTP gains             */
     opus_int8                   cbk_index[ MAX_NB_SUBFR ],                  /* O    Codebook Index                  */
     opus_int8                   *periodicity_index,                         /* O    Periodicity Index               */
     opus_int32                  *sum_log_gain_Q7,                           /* I/O  Cumulative max prediction gain  */
-    const opus_int32            W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ],  /* I    Error Weights in Q18            */
-    opus_int                    mu_Q9,                                      /* I    Mu value (R/D tradeoff)         */
-    opus_int                    lowComplexity,                              /* I    Flag for low complexity         */
-    const opus_int              nb_subfr,                                   /* I    number of subframes             */
+    opus_int                    *pred_gain_dB_Q7,                           /* O    LTP prediction gain             */
+    const opus_int32            XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I    Correlation matrix in Q18       */
+    const opus_int32            xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ],           /* I    Correlation vector in Q18       */
+    const opus_int              subfr_len,                                  /* I    Number of samples per subframe  */
+    const opus_int              nb_subfr,                                   /* I    Number of subframes             */
     int                         arch                                        /* I    Run-time architecture           */
 )
 {
@@ -49,16 +50,16 @@
     const opus_uint8     *cl_ptr_Q5;
     const opus_int8      *cbk_ptr_Q7;
     const opus_uint8     *cbk_gain_ptr_Q7;
-    const opus_int16     *b_Q14_ptr;
-    const opus_int32     *W_Q18_ptr;
-    opus_int32           rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14;
-    opus_int32           sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7;
+    const opus_int32     *XX_Q17_ptr, *xX_Q17_ptr;
+    opus_int32           res_nrg_Q15_subfr, res_nrg_Q15, rate_dist_Q7_subfr, rate_dist_Q7, min_rate_dist_Q7;
+    opus_int32           sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7;
+    opus_int             gain_Q7;
 
     /***************************************************/
     /* iterate over different codebooks with different */
     /* rates/distortions, and choose best */
     /***************************************************/
-    min_rate_dist_Q14 = silk_int32_MAX;
+    min_rate_dist_Q7 = silk_int32_MAX;
     best_sum_log_gain_Q7 = 0;
     for( k = 0; k < 3; k++ ) {
         /* Safety margin for pitch gain control, to take into account factors
@@ -70,53 +71,47 @@
         cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ];
         cbk_size   = silk_LTP_vq_sizes[          k ];
 
-        /* Set up pointer to first subframe */
-        W_Q18_ptr = W_Q18;
-        b_Q14_ptr = B_Q14;
+        /* Set up pointers to first subframe */
+        XX_Q17_ptr = XX_Q17;
+        xX_Q17_ptr = xX_Q17;
 
-        rate_dist_Q14 = 0;
+        res_nrg_Q15 = 0;
+        rate_dist_Q7 = 0;
         sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;
         for( j = 0; j < nb_subfr; j++ ) {
             max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )
                                         + SILK_FIX_CONST( 7, 7 ) ) - gain_safety;
-
             silk_VQ_WMat_EC(
                 &temp_idx[ j ],         /* O    index of best codebook vector                           */
-                &rate_dist_Q14_subfr,   /* O    best weighted quantization error + mu * rate            */
+                &res_nrg_Q15_subfr,     /* O    residual energy                                         */
+                &rate_dist_Q7_subfr,    /* O    best weighted quantization error + mu * rate            */
                 &gain_Q7,               /* O    sum of absolute LTP coefficients                        */
-                b_Q14_ptr,              /* I    input vector to be quantized                            */
-                W_Q18_ptr,              /* I    weighting matrix                                        */
+                XX_Q17_ptr,             /* I    correlation matrix                                      */
+                xX_Q17_ptr,             /* I    correlation vector                                      */
                 cbk_ptr_Q7,             /* I    codebook                                                */
                 cbk_gain_ptr_Q7,        /* I    codebook effective gains                                */
                 cl_ptr_Q5,              /* I    code length for each codebook vector                    */
-                mu_Q9,                  /* I    tradeoff between weighted error and rate                */
+                subfr_len,              /* I    number of samples per subframe                          */
                 max_gain_Q7,            /* I    maximum sum of absolute LTP coefficients                */
                 cbk_size,               /* I    number of vectors in codebook                           */
                 arch                    /* I    Run-time architecture                                   */
             );
 
-            rate_dist_Q14 = silk_ADD_POS_SAT32( rate_dist_Q14, rate_dist_Q14_subfr );
+            res_nrg_Q15  = silk_ADD_POS_SAT32( res_nrg_Q15, res_nrg_Q15_subfr );
+            rate_dist_Q7 = silk_ADD_POS_SAT32( rate_dist_Q7, rate_dist_Q7_subfr );
             sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7
                                 + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 ));
 
-            b_Q14_ptr += LTP_ORDER;
-            W_Q18_ptr += LTP_ORDER * LTP_ORDER;
+            XX_Q17_ptr += LTP_ORDER * LTP_ORDER;
+            xX_Q17_ptr += LTP_ORDER;
         }
 
-        /* Avoid never finding a codebook */
-        rate_dist_Q14 = silk_min( silk_int32_MAX - 1, rate_dist_Q14 );
-
-        if( rate_dist_Q14 < min_rate_dist_Q14 ) {
-            min_rate_dist_Q14 = rate_dist_Q14;
+        if( rate_dist_Q7 <= min_rate_dist_Q7 ) {
+            min_rate_dist_Q7 = rate_dist_Q7;
             *periodicity_index = (opus_int8)k;
             silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) );
             best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;
         }
-
-        /* Break early in low-complexity mode if rate distortion is below threshold */
-        if( lowComplexity && ( rate_dist_Q14 < silk_LTP_gain_middle_avg_RD_Q14 ) ) {
-            break;
-        }
     }
 
     cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ];
@@ -125,5 +120,13 @@
             B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 );
         }
     }
+
+    if( nb_subfr == 2 ) {
+        res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 1 );
+    } else {
+        res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 2 );
+    }
+
     *sum_log_gain_Q7 = best_sum_log_gain_Q7;
+    *pred_gain_dB_Q7 = (opus_int)silk_SMULBB( -3, silk_lin2log( res_nrg_Q15 ) - ( 15 << 7 ) );
 }
diff --git a/silk/structs.h b/silk/structs.h
index 827829d..4ff590b 100644
--- a/silk/structs.h
+++ b/silk/structs.h
@@ -48,6 +48,7 @@
     opus_int32                  sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
     opus_int32                  sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
     opus_int32                  sLF_AR_shp_Q14;
+    opus_int32                  sDiff_shp_Q14;
     opus_int                    lagPrev;
     opus_int                    sLTP_buf_idx;
     opus_int                    sLTP_shp_buf_idx;
@@ -86,6 +87,7 @@
     const opus_int16             quantStepSize_Q16;
     const opus_int16             invQuantStepSize_Q6;
     const opus_uint8             *CB1_NLSF_Q8;
+    const opus_int16             *CB1_Wght_Q9;
     const opus_uint8             *CB1_iCDF;
     const opus_uint8             *pred_Q8;
     const opus_uint8             *ec_sel;
@@ -169,8 +171,6 @@
     opus_int                     pitchEstimationComplexity;         /* Complexity level for pitch estimator                             */
     opus_int                     pitchEstimationLPCOrder;           /* Whitening filter order for pitch estimator                       */
     opus_int32                   pitchEstimationThreshold_Q16;      /* Threshold for pitch estimator                                    */
-    opus_int                     LTPQuantLowComplexity;             /* Flag for low complexity LTP quantization                         */
-    opus_int                     mu_LTP_Q9;                         /* Rate-distortion tradeoff in LTP quantization                     */
     opus_int32                   sum_log_gain_Q7;                   /* Cumulative max prediction gain                                   */
     opus_int                     NLSF_MSVQ_Survivors;               /* Number of survivors in NLSF MSVQ                                 */
     opus_int                     first_frame_after_reset;           /* Flag for deactivating NLSF interpolation, pitch prediction       */
@@ -301,6 +301,7 @@
     /* Stuff used for PLC */
     opus_int                    lossCnt;
     opus_int                    prevSignalType;
+    int                         arch;
 
     silk_PLC_struct sPLC;
 
diff --git a/silk/sum_sqr_shift.c b/silk/sum_sqr_shift.c
index 129df19..4fd0c3d 100644
--- a/silk/sum_sqr_shift.c
+++ b/silk/sum_sqr_shift.c
@@ -41,43 +41,40 @@
 )
 {
     opus_int   i, shft;
-    opus_int32 nrg_tmp, nrg;
+    opus_uint32 nrg_tmp;
+    opus_int32 nrg;
 
-    nrg  = 0;
-    shft = 0;
-    len--;
-    for( i = 0; i < len; i += 2 ) {
-        nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] );
-        nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] );
-        if( nrg < 0 ) {
-            /* Scale down */
-            nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
-            shft = 2;
-            i+=2;
-            break;
-        }
-    }
-    for( ; i < len; i += 2 ) {
+    /* Do a first run with the maximum shift we could have. */
+    shft = 31-silk_CLZ32(len);
+    /* Let's be conservative with rounding and start with nrg=len. */
+    nrg  = len;
+    for( i = 0; i < len - 1; i += 2 ) {
         nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
         nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
-        nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft );
-        if( nrg < 0 ) {
-            /* Scale down */
-            nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
-            shft += 2;
-        }
+        nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
     }
-    if( i == len ) {
+    if( i < len ) {
+        /* One sample left to process */
+        nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
+        nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
+    }
+    silk_assert( nrg >= 0 );
+    /* Make sure the result will fit in a 32-bit signed integer with two bits
+       of headroom. */
+    shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg));
+    nrg = 0;
+    for( i = 0 ; i < len - 1; i += 2 ) {
+        nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
+        nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
+        nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
+    }
+    if( i < len ) {
         /* One sample left to process */
         nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
         nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
     }
 
-    /* Make sure to have at least one extra leading zero (two leading zeros in total) */
-    if( nrg & 0xC0000000 ) {
-        nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
-        shft += 2;
-    }
+    silk_assert( nrg >= 0 );
 
     /* Output arguments */
     *shift  = shft;
diff --git a/silk/tables.h b/silk/tables.h
index 7fea6fd..8b0380e 100644
--- a/silk/tables.h
+++ b/silk/tables.h
@@ -76,10 +76,8 @@
 extern const opus_uint8  silk_LTP_per_index_iCDF[ 3 ];                                              /*   3 */
 extern const opus_uint8  * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ];                            /*   3 */
 extern const opus_uint8  * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ];                         /*   3 */
-extern const opus_int16  silk_LTP_gain_middle_avg_RD_Q14;
 extern const opus_int8   * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ];                                /* 168 */
 extern const opus_uint8  * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS];
-
 extern const opus_int8   silk_LTP_vq_sizes[ NB_LTP_CBKS ];                                          /*   3 */
 
 extern const opus_uint8  silk_LTPscale_iCDF[ 3 ];                                                   /*   4 */
diff --git a/silk/tables_LTP.c b/silk/tables_LTP.c
index 0e6a025..5e12c86 100644
--- a/silk/tables_LTP.c
+++ b/silk/tables_LTP.c
@@ -51,8 +51,6 @@
         24,     20,     16,     12,      9,      5,      2,      0
 };
 
-const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;
-
 static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
         15,    131,    138,    138,    155,    155,    173,    173
 };
diff --git a/silk/tables_NLSF_CB_NB_MB.c b/silk/tables_NLSF_CB_NB_MB.c
index 8c59d20..195d5b9 100644
--- a/silk/tables_NLSF_CB_NB_MB.c
+++ b/silk/tables_NLSF_CB_NB_MB.c
@@ -74,6 +74,41 @@
         64,     84,    104,    118,    156,    177,    201,    230
 };
 
+static const opus_int16 silk_NLSF_CB1_Wght_Q9[ 320 ] = {
+     2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287,
+     2888, 2580, 2394, 2367, 2314, 2274, 2274, 2274, 2274, 2194,
+     2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354,
+     3216, 2766, 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194,
+     2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, 2407, 2314,
+     3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261,
+     3282, 3141, 2580, 2394, 2247, 2221, 2207, 2194, 2194, 2114,
+     4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074,
+     3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221,
+     3338, 3488, 2726, 2194, 2261, 2460, 2354, 2367, 2207, 2101,
+     2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367,
+     3779, 3629, 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048,
+     3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, 2274, 2127,
+     3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101,
+     2873, 2981, 2633, 2367, 2407, 2354, 2194, 2247, 2247, 2114,
+     3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141,
+     3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114,
+     3141, 3272, 2460, 2061, 2287, 2500, 2367, 2487, 2434, 2181,
+     3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127,
+     3423, 3535, 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274,
+     3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, 2474, 2540,
+     3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261,
+     3028, 3272, 2740, 2888, 2740, 2154, 2127, 2287, 2234, 2247,
+     3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367,
+     3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167,
+     3338, 3366, 2846, 2780, 2327, 2154, 2274, 2287, 2114, 2061,
+     2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553,
+     2407, 2434, 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700,
+     3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, 2354, 2380,
+     2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367,
+     3676, 3713, 2234, 1838, 2181, 2753, 2726, 2673, 2513, 2207,
+     2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181
+};
+
 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,
@@ -150,6 +185,7 @@
     SILK_FIX_CONST( 0.18, 16 ),
     SILK_FIX_CONST( 1.0 / 0.18, 6 ),
     silk_NLSF_CB1_NB_MB_Q8,
+    silk_NLSF_CB1_Wght_Q9,
     silk_NLSF_CB1_iCDF_NB_MB,
     silk_NLSF_PRED_NB_MB_Q8,
     silk_NLSF_CB2_SELECT_NB_MB,
diff --git a/silk/tables_NLSF_CB_WB.c b/silk/tables_NLSF_CB_WB.c
index 50af87e..5cc9f57 100644
--- a/silk/tables_NLSF_CB_WB.c
+++ b/silk/tables_NLSF_CB_WB.c
@@ -98,6 +98,41 @@
        110,    119,    129,    141,    175,    198,    218,    237
 };
 
+static const opus_int16 silk_NLSF_CB1_WB_Wght_Q9[ 512 ] = {
+     3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846,
+     3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726,
+     3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925,
+     3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753,
+     5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888,
+     4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726,
+     3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991,
+     5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673,
+     5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700,
+     3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963,
+     4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873,
+     3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660,
+     3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580,
+     3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806,
+     5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753,
+     4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806,
+     5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620,
+     4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753,
+     3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846,
+     4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846,
+     2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740,
+     4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793,
+     4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780,
+     4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700,
+     4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888,
+     4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888,
+     5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925,
+     3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434,
+     2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010,
+     2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846,
+     3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888,
+     3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607
+};
+
 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,
@@ -188,6 +223,7 @@
     SILK_FIX_CONST( 0.15, 16 ),
     SILK_FIX_CONST( 1.0 / 0.15, 6 ),
     silk_NLSF_CB1_WB_Q8,
+    silk_NLSF_CB1_WB_Wght_Q9,
     silk_NLSF_CB1_iCDF_WB,
     silk_NLSF_PRED_WB_Q8,
     silk_NLSF_CB2_SELECT_WB,
diff --git a/silk/tests/test_unit_LPC_inv_pred_gain.c b/silk/tests/test_unit_LPC_inv_pred_gain.c
new file mode 100644
index 0000000..67067ce
--- /dev/null
+++ b/silk/tests/test_unit_LPC_inv_pred_gain.c
@@ -0,0 +1,129 @@
+/***********************************************************************
+Copyright (c) 2017 Google Inc., 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.
+- 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "celt/stack_alloc.h"
+#include "cpu_support.h"
+#include "SigProc_FIX.h"
+
+/* Computes the impulse response of the filter so we
+   can catch filters that are definitely unstable. Some
+   unstable filters may be classified as stable, but not
+   the other way around. */
+int check_stability(opus_int16 *A_Q12, int order) {
+    int i;
+    int j;
+    int sum_a, sum_abs_a;
+    sum_a = sum_abs_a = 0;
+    for( j = 0; j < order; j++ ) {
+        sum_a += A_Q12[ j ];
+        sum_abs_a += silk_abs( A_Q12[ j ] );
+    }
+    /* Check DC stability. */
+    if( sum_a >= 4096 ) {
+        return 0;
+    }
+    /* If the sum of absolute values is less than 1, the filter
+       has to be stable. */
+    if( sum_abs_a < 4096 ) {
+        return 1;
+    }
+    double y[SILK_MAX_ORDER_LPC] = {0};
+    y[0] = 1;
+    for( i = 0; i < 10000; i++ ) {
+        double sum = 0;
+        for( j = 0; j < order; j++ ) {
+            sum += y[ j ]*A_Q12[ j ];
+        }
+        for( j = order - 1; j > 0; j-- ) {
+            y[ j ] = y[ j - 1 ];
+        }
+        y[ 0 ] = sum*(1./4096);
+        /* If impulse response reaches +/- 10000, the filter
+           is definitely unstable. */
+        if( !(y[ 0 ] < 10000 && y[ 0 ] > -10000) ) {
+            return 0;
+        }
+        /* Test every 8 sample for low amplitude. */
+        if( ( i & 0x7 ) == 0 ) {
+            double amp = 0;
+            for( j = 0; j < order; j++ ) {
+                amp += fabs(y[j]);
+            }
+            if( amp < 0.00001 ) {
+                return 1;
+            }
+        }
+    }
+    return 1;
+}
+
+int main(void) {
+    const int arch = opus_select_arch();
+    /* Set to 10000 so all branches in C function are triggered */
+    const int loop_num = 10000;
+    int count = 0;
+    ALLOC_STACK;
+
+    /* FIXME: Make the seed random (with option to set it explicitly)
+       so we get wider coverage. */
+    srand(0);
+
+    printf("Testing silk_LPC_inverse_pred_gain() optimization ...\n");
+    for( count = 0; count < loop_num; count++ ) {
+        unsigned int i;
+        opus_int     order;
+        unsigned int shift;
+        opus_int16   A_Q12[ SILK_MAX_ORDER_LPC ];
+        opus_int32 gain;
+
+        for( order = 2; order <= SILK_MAX_ORDER_LPC; order += 2 ) { /* order must be even. */
+            for( shift = 0; shift < 16; shift++ ) { /* Different dynamic range. */
+                for( i = 0; i < SILK_MAX_ORDER_LPC; i++ ) {
+                    A_Q12[i] = ((opus_int16)rand()) >> shift;
+                }
+                gain = silk_LPC_inverse_pred_gain(A_Q12, order, arch);
+                /* Look for filters that silk_LPC_inverse_pred_gain() thinks are
+                   stable but definitely aren't. */
+                if( gain != 0 && !check_stability(A_Q12, order) ) {
+                    fprintf(stderr, "**Loop %4d failed!**\n", count);
+                    return 1;
+                }
+            }
+        }
+        if( !(count % 500) ) {
+            printf("Loop %4d passed\n", count);
+        }
+    }
+    printf("silk_LPC_inverse_pred_gain() optimization passed\n");
+    return 0;
+}
diff --git a/silk/tuning_parameters.h b/silk/tuning_parameters.h
index 5b8f404..d70275f 100644
--- a/silk/tuning_parameters.h
+++ b/silk/tuning_parameters.h
@@ -53,19 +53,12 @@
 /* LPC analysis regularization */
 #define FIND_LPC_COND_FAC                               1e-5f
 
-/* LTP analysis defines */
-#define FIND_LTP_COND_FAC                               1e-5f
-#define LTP_DAMPING                                     0.05f
-#define LTP_SMOOTHING                                   0.1f
-
-/* LTP quantization settings */
-#define MU_LTP_QUANT_NB                                 0.03f
-#define MU_LTP_QUANT_MB                                 0.025f
-#define MU_LTP_QUANT_WB                                 0.02f
-
 /* Max cumulative LTP gain */
 #define MAX_SUM_LOG_GAIN_DB                             250.0f
 
+/* LTP analysis defines */
+#define LTP_CORR_INV_MAX                                0.03f
+
 /***********************/
 /* High pass filtering */
 /***********************/
@@ -103,25 +96,16 @@
 #define SPARSE_SNR_INCR_dB                              2.0f
 
 /* threshold for sparseness measure above which to use lower quantization offset during unvoiced */
-#define SPARSENESS_THRESHOLD_QNT_OFFSET                 0.75f
+#define ENERGY_VARIATION_THRESHOLD_QNT_OFFSET           0.6f
 
 /* warping control */
 #define WARPING_MULTIPLIER                              0.015f
 
 /* fraction added to first autocorrelation value */
-#define SHAPE_WHITE_NOISE_FRACTION                      5e-5f
+#define SHAPE_WHITE_NOISE_FRACTION                      3e-5f
 
 /* noise shaping filter chirp factor */
-#define BANDWIDTH_EXPANSION                             0.95f
-
-/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */
-#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA              0.01f
-
-/* extra harmonic boosting (signal shaping) at low bitrates */
-#define LOW_RATE_HARMONIC_BOOST                         0.1f
-
-/* extra harmonic boosting (signal shaping) for noisy input signals */
-#define LOW_INPUT_QUALITY_HARMONIC_BOOST                0.1f
+#define BANDWIDTH_EXPANSION                             0.94f
 
 /* harmonic noise shaping */
 #define HARMONIC_SHAPING                                0.3f
diff --git a/silk/x86/NSQ_del_dec_sse.c b/silk/x86/NSQ_del_dec_sse.c
index 21d4a8b..c5212be 100644
--- a/silk/x86/NSQ_del_dec_sse.c
+++ b/silk/x86/NSQ_del_dec_sse.c
@@ -107,12 +107,12 @@
     opus_int            predictLPCOrder,        /* I    Prediction filter order             */
     opus_int            warping_Q16,            /* I                                        */
     opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
-    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
     opus_int            decisionDelay           /* I                                        */
 );
 
 void silk_NSQ_del_dec_sse4_1(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -234,7 +234,8 @@
                     psDD = &psDelDec[ Winner_ind ];
                     last_smple_idx = smpl_buf_idx + decisionDelay;
                     for( i = 0; i < decisionDelay; i++ ) {
-                        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
+                        last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
+                        if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
                         pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
                         pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
                             silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
@@ -285,7 +286,8 @@
     last_smple_idx = smpl_buf_idx + decisionDelay;
     Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
     for( i = 0; i < decisionDelay; i++ ) {
-        last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
+        last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
+        if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
         pulses[   i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
         pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
             silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
@@ -299,7 +301,6 @@
     NSQ->lagPrev        = pitchL[ psEncC->nb_subfr - 1 ];
 
     /* Save quantized speech signal */
-    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
     RESTORE_STACK;
@@ -333,7 +334,7 @@
     opus_int            predictLPCOrder,        /* I    Prediction filter order             */
     opus_int            warping_Q16,            /* I                                        */
     opus_int            nStatesDelayedDecision, /* I    Number of states in decision tree   */
-    opus_int            *smpl_buf_idx,          /* I    Index to newest samples in buffers  */
+    opus_int            *smpl_buf_idx,          /* I/O  Index to newest samples in buffers  */
     opus_int            decisionDelay           /* I                                        */
 )
 {
@@ -638,8 +639,9 @@
                 psSS[ 1 ].xq_Q14       = xq_Q14;
             }
         }
-        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK;                   /* Index to newest samples              */
-        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK;       /* Index to decisionDelay old samples   */
+        *smpl_buf_idx  = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
+        if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
+        last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
 
         /* Find winner */
         RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
diff --git a/silk/x86/NSQ_sse.c b/silk/x86/NSQ_sse.c
index bb3c5f1..6a9e6e9 100644
--- a/silk/x86/NSQ_sse.c
+++ b/silk/x86/NSQ_sse.c
@@ -71,7 +71,7 @@
 );
 
 void silk_NSQ_sse4_1(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -233,7 +233,6 @@
     NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
 
     /* Save quantized speech and noise shaping signals */
-    /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
     RESTORE_STACK;
diff --git a/silk/x86/main_sse.h b/silk/x86/main_sse.h
index d8d6131..2f15d44 100644
--- a/silk/x86/main_sse.h
+++ b/silk/x86/main_sse.h
@@ -34,6 +34,7 @@
 
 # if defined(OPUS_X86_MAY_HAVE_SSE4_1)
 
+#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
 #  define OVERRIDE_silk_VQ_WMat_EC
 
 void silk_VQ_WMat_EC_sse4_1(
@@ -79,11 +80,13 @@
                           mu_Q9, max_gain_Q7, L))
 
 #endif
+#endif
 
+#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
 #  define OVERRIDE_silk_NSQ
 
 void silk_NSQ_sse4_1(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -110,7 +113,7 @@
 #else
 
 extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -137,7 +140,7 @@
 #  define OVERRIDE_silk_NSQ_del_dec
 
 void silk_NSQ_del_dec_sse4_1(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -164,7 +167,7 @@
 #else
 
 extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -187,6 +190,7 @@
                            HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
 
 #endif
+#endif
 
 void silk_noise_shape_quantizer(
     silk_nsq_state      *NSQ,                   /* I/O  NSQ state                       */
@@ -238,39 +242,6 @@
      silk_encoder_state *psEnC,
      const opus_int16   pIn[]);
 
-#  define OVERRIDE_silk_warped_LPC_analysis_filter_FIX
-
-#endif
-
-void silk_warped_LPC_analysis_filter_FIX_sse4_1(
-          opus_int32            state[],                    /* I/O  State [order + 1]                   */
-          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */
-    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */
-    const opus_int16            input[],                    /* I    Input signal [length]               */
-    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */
-    const opus_int              length,                     /* I    Length of input signal              */
-    const opus_int              order                       /* I    Filter order (even)                 */
-);
-
-#if defined(OPUS_X86_PRESUME_SSE4_1)
-#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
-    ((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
-
-#else
-
-extern void (*const SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[OPUS_ARCHMASK + 1])(
-          opus_int32            state[],                    /* I/O  State [order + 1]                   */
-          opus_int32            res_Q2[],                   /* O    Residual signal [length]            */
-    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */
-    const opus_int16            input[],                    /* I    Input signal [length]               */
-    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */
-    const opus_int              length,                     /* I    Length of input signal              */
-    const opus_int              order                       /* I    Filter order (even)                 */
-);
-
-#  define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
-    ((*SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[(arch) & OPUS_ARCHMASK])(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
-
 #endif
 
 # endif
diff --git a/silk/x86/x86_silk_map.c b/silk/x86/x86_silk_map.c
index 818841f..32dcc3c 100644
--- a/silk/x86/x86_silk_map.c
+++ b/silk/x86/x86_silk_map.c
@@ -66,8 +66,9 @@
   MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 )  /* avx */
 };
 
+#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
 void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -89,7 +90,9 @@
   MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */
   MAY_HAVE_SSE4_1( silk_NSQ )  /* avx */
 };
+#endif
 
+#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
 void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )(
     opus_int8                   *ind,                           /* O    index of best codebook vector               */
     opus_int32                  *rate_dist_Q14,                 /* O    best weighted quant error + mu * rate       */
@@ -109,9 +112,11 @@
   MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */
   MAY_HAVE_SSE4_1( silk_VQ_WMat_EC )  /* avx */
 };
+#endif
 
+#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
 void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )(
-    const silk_encoder_state    *psEncC,                                    /* I/O  Encoder State                   */
+    const silk_encoder_state    *psEncC,                                    /* I    Encoder State                   */
     silk_nsq_state              *NSQ,                                       /* I/O  NSQ state                       */
     SideInfoIndices             *psIndices,                                 /* I/O  Quantization Indices            */
     const opus_int32            x_Q3[],                                     /* I    Prefiltered input signal        */
@@ -133,25 +138,10 @@
   MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */
   MAY_HAVE_SSE4_1( silk_NSQ_del_dec )  /* avx */
 };
+#endif
 
 #if defined(FIXED_POINT)
 
-void (*const SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[ OPUS_ARCHMASK + 1 ] )(
-    opus_int32                  state[],                    /* I/O  State [order + 1]                   */
-    opus_int32                  res_Q2[],                   /* O    Residual signal [length]            */
-    const opus_int16            coef_Q13[],                 /* I    Coefficients [order]                */
-    const opus_int16            input[],                    /* I    Input signal [length]               */
-    const opus_int16            lambda_Q16,                 /* I    Warping factor                      */
-    const opus_int              length,                     /* I    Length of input signal              */
-    const opus_int              order                       /* I    Filter order (even)                 */
-) = {
-  silk_warped_LPC_analysis_filter_FIX_c,                  /* non-sse */
-  silk_warped_LPC_analysis_filter_FIX_c,
-  silk_warped_LPC_analysis_filter_FIX_c,
-  MAY_HAVE_SSE4_1( silk_warped_LPC_analysis_filter_FIX ), /* sse4.1 */
-  MAY_HAVE_SSE4_1( silk_warped_LPC_analysis_filter_FIX )  /* avx */
-};
-
 void (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )(
     opus_int32                  *res_nrg,           /* O    Residual energy                                             */
     opus_int                    *res_nrg_Q,         /* O    Residual energy Q value                                     */
diff --git a/silk_headers.mk b/silk_headers.mk
index f8bf1d2..2588067 100644
--- a/silk_headers.mk
+++ b/silk_headers.mk
@@ -22,16 +22,19 @@
 silk/resampler_structs.h \
 silk/SigProc_FIX.h \
 silk/x86/SigProc_FIX_sse.h \
+silk/arm/biquad_alt_arm.h \
+silk/arm/LPC_inv_pred_gain_arm.h \
 silk/arm/macros_armv4.h \
 silk/arm/macros_armv5e.h \
 silk/arm/macros_arm64.h \
 silk/arm/SigProc_FIX_armv4.h \
 silk/arm/SigProc_FIX_armv5e.h \
+silk/arm/NSQ_del_dec_arm.h \
 silk/arm/NSQ_neon.h \
 silk/fixed/main_FIX.h \
 silk/fixed/structs_FIX.h \
+silk/fixed/arm/warped_autocorrelation_FIX_arm.h \
 silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h \
-silk/fixed/mips/prefilter_FIX_mipsr1.h \
 silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h \
 silk/float/main_FLP.h \
 silk/float/structs_FLP.h \
diff --git a/silk_sources.mk b/silk_sources.mk
index 7229ee3..6d14392 100644
--- a/silk_sources.mk
+++ b/silk_sources.mk
@@ -74,7 +74,8 @@
 silk/stereo_decode_pred.c \
 silk/stereo_encode_pred.c \
 silk/stereo_find_predictor.c \
-silk/stereo_quant_pred.c
+silk/stereo_quant_pred.c \
+silk/LPC_fit.c
 
 SILK_SOURCES_SSE4_1 = silk/x86/NSQ_sse.c \
 silk/x86/NSQ_del_dec_sse.c \
@@ -84,6 +85,9 @@
 
 SILK_SOURCES_ARM_NEON_INTR = \
 silk/arm/arm_silk_map.c \
+silk/arm/biquad_alt_neon_intr.c \
+silk/arm/LPC_inv_pred_gain_neon_intr.c \
+silk/arm/NSQ_del_dec_neon_intr.c \
 silk/arm/NSQ_neon.c
 
 SILK_SOURCES_FIXED = \
@@ -96,12 +100,10 @@
 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 \
@@ -114,8 +116,10 @@
 silk/fixed/schur_FIX.c
 
 SILK_SOURCES_FIXED_SSE4_1 = silk/fixed/x86/vector_ops_FIX_sse.c \
-silk/fixed/x86/burg_modified_FIX_sse.c \
-silk/fixed/x86/prefilter_FIX_sse.c
+silk/fixed/x86/burg_modified_FIX_sse.c
+
+SILK_SOURCES_FIXED_ARM_NEON_INTR = \
+silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
 
 SILK_SOURCES_FLOAT = \
 silk/float/apply_sine_window_FLP.c \
@@ -129,11 +133,9 @@
 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 \
@@ -142,7 +144,6 @@
 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 \
diff --git a/src/analysis.c b/src/analysis.c
index 663431a..f4160e4 100644
--- a/src/analysis.c
+++ b/src/analysis.c
@@ -29,20 +29,27 @@
 #include "config.h"
 #endif
 
+#define ANALYSIS_C
+
+#include <stdio.h>
+
+#include "mathops.h"
 #include "kiss_fft.h"
 #include "celt.h"
 #include "modes.h"
 #include "arch.h"
 #include "quant_bands.h"
-#include <stdio.h>
 #include "analysis.h"
 #include "mlp.h"
 #include "stack_alloc.h"
+#include "float_cast.h"
 
 #ifndef M_PI
 #define M_PI 3.141592653
 #endif
 
+#ifndef DISABLE_FLOAT_API
+
 static const float dct_table[128] = {
         0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
         0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
@@ -96,52 +103,118 @@
 };
 
 static const int tbands[NB_TBANDS+1] = {
-       2,  4,  6,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120
+      4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240
 };
 
-static const int extra_bands[NB_TOT_BANDS+1] = {
-      1, 2,  4,  6,  8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200
-};
-
-/*static const float tweight[NB_TBANDS+1] = {
-      .3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5
-};*/
-
 #define NB_TONAL_SKIP_BANDS 9
 
-#define cA 0.43157974f
-#define cB 0.67848403f
-#define cC 0.08595542f
-#define cE ((float)M_PI/2)
-static OPUS_INLINE float fast_atan2f(float y, float x) {
-   float x2, y2;
-   /* Should avoid underflow on the values we'll get */
-   if (ABS16(x)+ABS16(y)<1e-9f)
-   {
-      x*=1e12f;
-      y*=1e12f;
-   }
-   x2 = x*x;
-   y2 = y*y;
-   if(x2<y2){
-      float den = (y2 + cB*x2) * (y2 + cC*x2);
-      if (den!=0)
-         return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
-      else
-         return (y<0 ? -cE : cE);
-   }else{
-      float den = (x2 + cB*y2) * (x2 + cC*y2);
-      if (den!=0)
-         return  x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
-      else
-         return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
-   }
+static opus_val32 silk_resampler_down2_hp(
+    opus_val32                  *S,                 /* I/O  State vector [ 2 ]                                          */
+    opus_val32                  *out,               /* O    Output signal [ floor(len/2) ]                              */
+    const opus_val32            *in,                /* I    Input signal [ len ]                                        */
+    int                         inLen               /* I    Number of input samples                                     */
+)
+{
+    int k, len2 = inLen/2;
+    opus_val32 in32, out32, out32_hp, Y, X;
+    opus_val64 hp_ener = 0;
+    /* Internal variables and state are in Q10 format */
+    for( k = 0; k < len2; k++ ) {
+        /* Convert to Q10 */
+        in32 = in[ 2 * k ];
+
+        /* All-pass section for even input sample */
+        Y      = SUB32( in32, S[ 0 ] );
+        X      = MULT16_32_Q15(QCONST16(0.6074371f, 15), Y);
+        out32  = ADD32( S[ 0 ], X );
+        S[ 0 ] = ADD32( in32, X );
+        out32_hp = out32;
+        /* Convert to Q10 */
+        in32 = in[ 2 * k + 1 ];
+
+        /* All-pass section for odd input sample, and add to output of previous section */
+        Y      = SUB32( in32, S[ 1 ] );
+        X      = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
+        out32  = ADD32( out32, S[ 1 ] );
+        out32  = ADD32( out32, X );
+        S[ 1 ] = ADD32( in32, X );
+
+        Y      = SUB32( -in32, S[ 2 ] );
+        X      = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
+        out32_hp  = ADD32( out32_hp, S[ 2 ] );
+        out32_hp  = ADD32( out32_hp, X );
+        S[ 2 ] = ADD32( -in32, X );
+
+        hp_ener += out32_hp*(opus_val64)out32_hp;
+        /* Add, convert back to int16 and store to output */
+        out[ k ] = HALF32(out32);
+    }
+#ifdef FIXED_POINT
+    /* len2 can be up to 480, so we shift by 8 more to make it fit. */
+    hp_ener = hp_ener >> (2*SIG_SHIFT + 8);
+#endif
+    return (opus_val32)hp_ener;
 }
 
-void tonality_analysis_init(TonalityAnalysisState *tonal)
+static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opus_val32 *y, opus_val32 S[3], int subframe, int offset, int c1, int c2, int C, int Fs)
+{
+   VARDECL(opus_val32, tmp);
+   opus_val32 scale;
+   int j;
+   opus_val32 ret = 0;
+   SAVE_STACK;
+
+   if (subframe==0) return 0;
+   if (Fs == 48000)
+   {
+      subframe *= 2;
+      offset *= 2;
+   } else if (Fs == 16000) {
+      subframe = subframe*2/3;
+      offset = offset*2/3;
+   }
+   ALLOC(tmp, subframe, opus_val32);
+
+   downmix(_x, tmp, subframe, offset, c1, c2, C);
+#ifdef FIXED_POINT
+   scale = (1<<SIG_SHIFT);
+#else
+   scale = 1.f/32768;
+#endif
+   if (c2==-2)
+      scale /= C;
+   else if (c2>-1)
+      scale /= 2;
+   for (j=0;j<subframe;j++)
+      tmp[j] *= scale;
+   if (Fs == 48000)
+   {
+      ret = silk_resampler_down2_hp(S, y, tmp, subframe);
+   } else if (Fs == 24000) {
+      OPUS_COPY(y, tmp, subframe);
+   } else if (Fs == 16000) {
+      VARDECL(opus_val32, tmp3x);
+      ALLOC(tmp3x, 3*subframe, opus_val32);
+      /* Don't do this at home! This resampler is horrible and it's only (barely)
+         usable for the purpose of the analysis because we don't care about all
+         the aliasing between 8 kHz and 12 kHz. */
+      for (j=0;j<subframe;j++)
+      {
+         tmp3x[3*j] = tmp[j];
+         tmp3x[3*j+1] = tmp[j];
+         tmp3x[3*j+2] = tmp[j];
+      }
+      silk_resampler_down2_hp(S, y, tmp3x, 3*subframe);
+   }
+   RESTORE_STACK;
+   return ret;
+}
+
+void tonality_analysis_init(TonalityAnalysisState *tonal, opus_int32 Fs)
 {
   /* Initialize reusable fields. */
   tonal->arch = opus_select_arch();
+  tonal->Fs = Fs;
   /* Clear remaining fields. */
   tonality_analysis_reset(tonal);
 }
@@ -151,6 +224,8 @@
   /* Clear non-reusable fields. */
   char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START;
   OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal));
+  tonal->music_confidence = .9f;
+  tonal->speech_confidence = .1f;
 }
 
 void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)
@@ -158,6 +233,9 @@
    int pos;
    int curr_lookahead;
    float psum;
+   float tonality_max;
+   float tonality_avg;
+   int tonality_count;
    int i;
 
    pos = tonal->read_pos;
@@ -165,7 +243,8 @@
    if (curr_lookahead<0)
       curr_lookahead += DETECT_SIZE;
 
-   if (len > 480 && pos != tonal->write_pos)
+   /* On long frames, look at the second analysis window rather than the first. */
+   if (len > tonal->Fs/50 && pos != tonal->write_pos)
    {
       pos++;
       if (pos==DETECT_SIZE)
@@ -176,18 +255,32 @@
    if (pos<0)
       pos = DETECT_SIZE-1;
    OPUS_COPY(info_out, &tonal->info[pos], 1);
-   tonal->read_subframe += len/120;
-   while (tonal->read_subframe>=4)
+   tonality_max = tonality_avg = info_out->tonality;
+   tonality_count = 1;
+   /* If possible, look ahead for a tone to compensate for the delay in the tone detector. */
+   for (i=0;i<3;i++)
    {
-      tonal->read_subframe -= 4;
+      pos++;
+      if (pos==DETECT_SIZE)
+         pos = 0;
+      if (pos == tonal->write_pos)
+         break;
+      tonality_max = MAX32(tonality_max, tonal->info[pos].tonality);
+      tonality_avg += tonal->info[pos].tonality;
+      tonality_count++;
+   }
+   info_out->tonality = MAX32(tonality_avg/tonality_count, tonality_max-.2f);
+   tonal->read_subframe += len/(tonal->Fs/400);
+   while (tonal->read_subframe>=8)
+   {
+      tonal->read_subframe -= 8;
       tonal->read_pos++;
    }
    if (tonal->read_pos>=DETECT_SIZE)
       tonal->read_pos-=DETECT_SIZE;
 
-   /* Compensate for the delay in the features themselves.
-      FIXME: Need a better estimate the 10 I just made up */
-   curr_lookahead = IMAX(curr_lookahead-10, 0);
+   /* The -1 is to compensate for the delay in the features themselves. */
+   curr_lookahead = IMAX(curr_lookahead-1, 0);
 
    psum=0;
    /* Summing the probability of transition patterns that involve music at
@@ -197,11 +290,28 @@
    for (;i<DETECT_SIZE;i++)
       psum += tonal->pspeech[i];
    psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;
-   /*printf("%f %f %f\n", psum, info_out->music_prob, info_out->tonality);*/
+   /*printf("%f %f %f %f %f\n", psum, info_out->music_prob, info_out->vad_prob, info_out->activity_probability, info_out->tonality);*/
 
    info_out->music_prob = psum;
 }
 
+static const float std_feature_bias[9] = {
+      5.684947f, 3.475288f, 1.770634f, 1.599784f, 3.773215f,
+      2.163313f, 1.260756f, 1.116868f, 1.918795f
+};
+
+#define LEAKAGE_OFFSET 2.5f
+#define LEAKAGE_SLOPE 2.f
+
+#ifdef FIXED_POINT
+/* For fixed-point, the input is +/-2^15 shifted up by SIG_SHIFT, so we need to
+   compensate for that in the energy. */
+#define SCALE_COMPENS (1.f/((opus_int32)1<<(15+SIG_SHIFT)))
+#define SCALE_ENER(e) ((SCALE_COMPENS*SCALE_COMPENS)*(e))
+#else
+#define SCALE_ENER(e) (e)
+#endif
+
 static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
 {
     int i, b;
@@ -235,19 +345,41 @@
     float noise_floor;
     int remaining;
     AnalysisInfo *info;
+    float hp_ener;
+    float tonality2[240];
+    float midE[8];
+    float spec_variability=0;
+    float band_log2[NB_TBANDS+1];
+    float leakage_from[NB_TBANDS+1];
+    float leakage_to[NB_TBANDS+1];
     SAVE_STACK;
 
-    tonal->last_transition++;
-    alpha = 1.f/IMIN(20, 1+tonal->count);
-    alphaE = 1.f/IMIN(50, 1+tonal->count);
-    alphaE2 = 1.f/IMIN(1000, 1+tonal->count);
+    alpha = 1.f/IMIN(10, 1+tonal->count);
+    alphaE = 1.f/IMIN(25, 1+tonal->count);
+    alphaE2 = 1.f/IMIN(500, 1+tonal->count);
 
-    if (tonal->count<4)
-       tonal->music_prob = .5;
+    if (tonal->Fs == 48000)
+    {
+       /* len and offset are now at 24 kHz. */
+       len/= 2;
+       offset /= 2;
+    } else if (tonal->Fs == 16000) {
+       len = 3*len/2;
+       offset = 3*offset/2;
+    }
+
+    if (tonal->count<4) {
+       if (tonal->application == OPUS_APPLICATION_VOIP)
+          tonal->music_prob = .1f;
+       else
+          tonal->music_prob = .625f;
+    }
     kfft = celt_mode->mdct.kfft[0];
     if (tonal->count==0)
        tonal->mem_fill = 240;
-    downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C);
+    tonal->hp_ener_accum += (float)downmix_and_resample(downmix, x,
+          &tonal->inmem[tonal->mem_fill], tonal->downmix_state,
+          IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C, tonal->Fs);
     if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
     {
        tonal->mem_fill += len;
@@ -255,6 +387,7 @@
        RESTORE_STACK;
        return;
     }
+    hp_ener = tonal->hp_ener_accum;
     info = &tonal->info[tonal->write_pos++];
     if (tonal->write_pos>=DETECT_SIZE)
        tonal->write_pos-=DETECT_SIZE;
@@ -273,7 +406,9 @@
     }
     OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
     remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
-    downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);
+    tonal->hp_ener_accum = (float)downmix_and_resample(downmix, x,
+          &tonal->inmem[240], tonal->downmix_state, remaining,
+          offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C, tonal->Fs);
     tonal->mem_fill = 240 + remaining;
     opus_fft(kfft, in, out, tonal->arch);
 #ifndef FIXED_POINT
@@ -305,24 +440,31 @@
        d_angle2 = angle2 - angle;
        d2_angle2 = d_angle2 - d_angle;
 
-       mod1 = d2_angle - (float)floor(.5+d2_angle);
+       mod1 = d2_angle - (float)float2int(d2_angle);
        noisiness[i] = ABS16(mod1);
        mod1 *= mod1;
        mod1 *= mod1;
 
-       mod2 = d2_angle2 - (float)floor(.5+d2_angle2);
+       mod2 = d2_angle2 - (float)float2int(d2_angle2);
        noisiness[i] += ABS16(mod2);
        mod2 *= mod2;
        mod2 *= mod2;
 
-       avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);
+       avg_mod = .25f*(d2A[i]+mod1+2*mod2);
+       /* This introduces an extra delay of 2 frames in the detection. */
        tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
+       /* No delay on this detection, but it's less reliable. */
+       tonality2[i] = 1.f/(1.f+40.f*16.f*pi4*mod2)-.015f;
 
        A[i] = angle2;
        dA[i] = d_angle2;
        d2A[i] = mod2;
     }
-
+    for (i=2;i<N2-1;i++)
+    {
+       float tt = MIN32(tonality2[i], MAX32(tonality2[i-1], tonality2[i+1]));
+       tonality[i] = .9f*MAX32(tonality[i], tt-.1f);
+    }
     frame_tonality = 0;
     max_frame_tonality = 0;
     /*tw_sum = 0;*/
@@ -339,6 +481,22 @@
     }
     relativeE = 0;
     frame_loudness = 0;
+    /* The energy of the very first band is special because of DC. */
+    {
+       float E = 0;
+       float X1r, X2r;
+       X1r = 2*(float)out[0].r;
+       X2r = 2*(float)out[0].i;
+       E = X1r*X1r + X2r*X2r;
+       for (i=1;i<4;i++)
+       {
+          float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+                     + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
+          E += binE;
+       }
+       E = SCALE_ENER(E);
+       band_log2[0] = .5f*1.442695f*(float)log(E+1e-10f);
+    }
     for (b=0;b<NB_TBANDS;b++)
     {
        float E=0, tE=0, nE=0;
@@ -348,12 +506,9 @@
        {
           float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
                      + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
-#ifdef FIXED_POINT
-          /* FIXME: It's probably best to change the BFCC filter initial state instead */
-          binE *= 5.55e-17f;
-#endif
+          binE = SCALE_ENER(binE);
           E += binE;
-          tE += binE*tonality[i];
+          tE += binE*MAX32(0, tonality[i]);
           nE += binE*2.f*(.5f-noisiness[i]);
        }
 #ifndef FIXED_POINT
@@ -371,14 +526,27 @@
 
        frame_loudness += (float)sqrt(E+1e-10f);
        logE[b] = (float)log(E+1e-10f);
-       tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
-       tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
-       if (tonal->highE[b] < tonal->lowE[b]+1.f)
+       band_log2[b+1] = .5f*1.442695f*(float)log(E+1e-10f);
+       tonal->logE[tonal->E_count][b] = logE[b];
+       if (tonal->count==0)
+          tonal->highE[b] = tonal->lowE[b] = logE[b];
+       if (tonal->highE[b] > tonal->lowE[b] + 7.5)
        {
-          tonal->highE[b]+=.5f;
-          tonal->lowE[b]-=.5f;
+          if (tonal->highE[b] - logE[b] > logE[b] - tonal->lowE[b])
+             tonal->highE[b] -= .01f;
+          else
+             tonal->lowE[b] += .01f;
        }
-       relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]);
+       if (logE[b] > tonal->highE[b])
+       {
+          tonal->highE[b] = logE[b];
+          tonal->lowE[b] = MAX32(tonal->highE[b]-15, tonal->lowE[b]);
+       } else if (logE[b] < tonal->lowE[b])
+       {
+          tonal->lowE[b] = logE[b];
+          tonal->highE[b] = MIN32(tonal->lowE[b]+15, tonal->highE[b]);
+       }
+       relativeE += (logE[b]-tonal->lowE[b])/(1e-15f + (tonal->highE[b]-tonal->lowE[b]));
 
        L1=L2=0;
        for (i=0;i<NB_FRAMES;i++)
@@ -410,27 +578,74 @@
        tonal->prev_band_tonality[b] = band_tonality[b];
     }
 
+    leakage_from[0] = band_log2[0];
+    leakage_to[0] = band_log2[0] - LEAKAGE_OFFSET;
+    for (b=1;b<NB_TBANDS+1;b++)
+    {
+       float leak_slope = LEAKAGE_SLOPE*(tbands[b]-tbands[b-1])/4;
+       leakage_from[b] = MIN16(leakage_from[b-1]+leak_slope, band_log2[b]);
+       leakage_to[b] = MAX16(leakage_to[b-1]-leak_slope, band_log2[b]-LEAKAGE_OFFSET);
+    }
+    for (b=NB_TBANDS-2;b>=0;b--)
+    {
+       float leak_slope = LEAKAGE_SLOPE*(tbands[b+1]-tbands[b])/4;
+       leakage_from[b] = MIN16(leakage_from[b+1]+leak_slope, leakage_from[b]);
+       leakage_to[b] = MAX16(leakage_to[b+1]-leak_slope, leakage_to[b]);
+    }
+    celt_assert(NB_TBANDS+1 <= LEAK_BANDS);
+    for (b=0;b<NB_TBANDS+1;b++)
+    {
+       /* leak_boost[] is made up of two terms. The first, based on leakage_to[],
+          represents the boost needed to overcome the amount of analysis leakage
+          cause in a weaker band b by louder neighbouring bands.
+          The second, based on leakage_from[], applies to a loud band b for
+          which the quantization noise causes synthesis leakage to the weaker
+          neighbouring bands. */
+       float boost = MAX16(0, leakage_to[b] - band_log2[b]) +
+             MAX16(0, band_log2[b] - (leakage_from[b]+LEAKAGE_OFFSET));
+       info->leak_boost[b] = IMIN(255, (int)floor(.5 + 64.f*boost));
+    }
+    for (;b<LEAK_BANDS;b++) info->leak_boost[b] = 0;
+
+    for (i=0;i<NB_FRAMES;i++)
+    {
+       int j;
+       float mindist = 1e15f;
+       for (j=0;j<NB_FRAMES;j++)
+       {
+          int k;
+          float dist=0;
+          for (k=0;k<NB_TBANDS;k++)
+          {
+             float tmp;
+             tmp = tonal->logE[i][k] - tonal->logE[j][k];
+             dist += tmp*tmp;
+          }
+          if (j!=i)
+             mindist = MIN32(mindist, dist);
+       }
+       spec_variability += mindist;
+    }
+    spec_variability = (float)sqrt(spec_variability/NB_FRAMES/NB_TBANDS);
     bandwidth_mask = 0;
     bandwidth = 0;
     maxE = 0;
     noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
-#ifdef FIXED_POINT
-    noise_floor *= 1<<(15+SIG_SHIFT);
-#endif
     noise_floor *= noise_floor;
-    for (b=0;b<NB_TOT_BANDS;b++)
+    for (b=0;b<NB_TBANDS;b++)
     {
        float E=0;
        int band_start, band_end;
        /* Keep a margin of 300 Hz for aliasing */
-       band_start = extra_bands[b];
-       band_end = extra_bands[b+1];
+       band_start = tbands[b];
+       band_end = tbands[b+1];
        for (i=band_start;i<band_end;i++)
        {
           float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
                      + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
           E += binE;
        }
+       E = SCALE_ENER(E);
        maxE = MAX32(maxE, E);
        tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
        E = MAX32(E, tonal->meanE[b]);
@@ -441,14 +656,36 @@
           2) less than 90 dB below the peak band (maximal masking possible considering
              both the ATH and the loudness-dependent slope of the spreading function)
           3) above the PCM quantization noise floor
+          We use b+1 because the first CELT band isn't included in tbands[]
        */
        if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start))
-          bandwidth = b;
+          bandwidth = b+1;
+    }
+    /* Special case for the last two bands, for which we don't have spectrum but only
+       the energy above 12 kHz. */
+    if (tonal->Fs == 48000) {
+       float ratio;
+       float E = hp_ener*(1.f/(240*240));
+       ratio = tonal->prev_bandwidth==20 ? 0.03f : 0.07f;
+#ifdef FIXED_POINT
+       /* silk_resampler_down2_hp() shifted right by an extra 8 bits. */
+       E *= 256.f*(1.f/Q15ONE)*(1.f/Q15ONE);
+#endif
+       maxE = MAX32(maxE, E);
+       tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
+       E = MAX32(E, tonal->meanE[b]);
+       /* Use a simple follower with 13 dB/Bark slope for spreading function */
+       bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
+       if (E>ratio*bandwidth_mask && E*1e9f > maxE && E > noise_floor*160)
+          bandwidth = 20;
+       /* This detector is unreliable, so if the bandwidth is close to SWB, assume it's FB. */
+       if (bandwidth >= 17)
+          bandwidth = 20;
     }
     if (tonal->count<=2)
        bandwidth = 20;
     frame_loudness = 20*(float)log10(frame_loudness);
-    tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);
+    tonal->Etracker = MAX32(tonal->Etracker-.003f, frame_loudness);
     tonal->lowECount *= (1-alphaE);
     if (frame_loudness < tonal->Etracker-30)
        tonal->lowECount += alphaE;
@@ -460,11 +697,18 @@
           sum += dct_table[i*16+b]*logE[b];
        BFCC[i] = sum;
     }
+    for (i=0;i<8;i++)
+    {
+       float sum=0;
+       for (b=0;b<16;b++)
+          sum += dct_table[i*16+b]*.5f*(tonal->highE[b]+tonal->lowE[b]);
+       midE[i] = sum;
+    }
 
     frame_stationarity /= NB_TBANDS;
     relativeE /= NB_TBANDS;
     if (tonal->count<10)
-       relativeE = .5;
+       relativeE = .5f;
     frame_noisiness /= NB_TBANDS;
 #if 1
     info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
@@ -479,7 +723,7 @@
     info->tonality_slope = slope;
 
     tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
-    tonal->count++;
+    tonal->count = IMIN(tonal->count+1, ANALYSIS_COUNT_MAX);
     info->tonality = frame_tonality;
 
     for (i=0;i<4;i++)
@@ -498,6 +742,8 @@
        for (i=0;i<9;i++)
           tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
     }
+    for (i=0;i<4;i++)
+       features[i] = BFCC[i]-midE[i];
 
     for (i=0;i<8;i++)
     {
@@ -507,24 +753,26 @@
        tonal->mem[i] = BFCC[i];
     }
     for (i=0;i<9;i++)
-       features[11+i] = (float)sqrt(tonal->std[i]);
-    features[20] = info->tonality;
-    features[21] = info->activity;
-    features[22] = frame_stationarity;
-    features[23] = info->tonality_slope;
-    features[24] = tonal->lowECount;
+       features[11+i] = (float)sqrt(tonal->std[i]) - std_feature_bias[i];
+    features[18] = spec_variability - 0.78f;
+    features[20] = info->tonality - 0.154723f;
+    features[21] = info->activity - 0.724643f;
+    features[22] = frame_stationarity - 0.743717f;
+    features[23] = info->tonality_slope + 0.069216f;
+    features[24] = tonal->lowECount - 0.067930f;
 
-#ifndef DISABLE_FLOAT_API
     mlp_process(&net, features, frame_probs);
     frame_probs[0] = .5f*(frame_probs[0]+1);
     /* Curve fitting between the MLP probability and the actual probability */
-    frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);
+    /*frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);*/
     /* Probability of active audio (as opposed to silence) */
     frame_probs[1] = .5f*frame_probs[1]+.5f;
-    /* Consider that silence has a 50-50 probability. */
-    frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f;
+    frame_probs[1] *= frame_probs[1];
 
-    /*printf("%f %f ", frame_probs[0], frame_probs[1]);*/
+    /* Probability of speech or music vs noise */
+    info->activity_probability = frame_probs[1];
+
+    /*printf("%f %f\n", frame_probs[0], frame_probs[1]);*/
     {
        /* Probability of state transition */
        float tau;
@@ -542,12 +790,32 @@
        float music0;
        float p, q;
 
+       /* More silence transitions for speech than for music. */
+       tau = .001f*tonal->music_prob + .01f*(1-tonal->music_prob);
+       p = MAX16(.05f,MIN16(.95f,frame_probs[1]));
+       q = MAX16(.05f,MIN16(.95f,tonal->vad_prob));
+       beta = .02f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
+       /* p0 and p1 are the probabilities of speech and music at this frame
+          using only information from previous frame and applying the
+          state transition model */
+       p0 = (1-tonal->vad_prob)*(1-tau) +    tonal->vad_prob *tau;
+       p1 =    tonal->vad_prob *(1-tau) + (1-tonal->vad_prob)*tau;
+       /* We apply the current probability with exponent beta to work around
+          the fact that the probability estimates aren't independent. */
+       p0 *= (float)pow(1-frame_probs[1], beta);
+       p1 *= (float)pow(frame_probs[1], beta);
+       /* Normalise the probabilities to get the Marokv probability of music. */
+       tonal->vad_prob = p1/(p0+p1);
+       info->vad_prob = tonal->vad_prob;
+       /* Consider that silence has a 50-50 probability of being speech or music. */
+       frame_probs[0] = tonal->vad_prob*frame_probs[0] + (1-tonal->vad_prob)*.5f;
+
        /* One transition every 3 minutes of active audio */
-       tau = .00005f*frame_probs[1];
+       tau = .0001f;
        /* Adapt beta based on how "unexpected" the new prob is */
        p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
        q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
-       beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
+       beta = .02f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
        /* p0 and p1 are the probabilities of speech and music at this frame
           using only information from previous frame and applying the
           state transition model */
@@ -561,6 +829,7 @@
        tonal->music_prob = p1/(p0+p1);
        info->music_prob = tonal->music_prob;
 
+       /*printf("%f %f %f %f\n", frame_probs[0], frame_probs[1], tonal->music_prob, tonal->vad_prob);*/
        /* This chunk of code deals with delayed decision. */
        psum=1e-20f;
        /* Instantaneous probability of speech and music, with beta pre-applied. */
@@ -568,8 +837,11 @@
        music0  = (float)pow(frame_probs[0], beta);
        if (tonal->count==1)
        {
-          tonal->pspeech[0]=.5;
-          tonal->pmusic [0]=.5;
+          if (tonal->application == OPUS_APPLICATION_VOIP)
+             tonal->pmusic[0] = .1f;
+          else
+             tonal->pmusic[0] = .625f;
+          tonal->pspeech[0] = 1-tonal->pmusic[0];
        }
        /* Updated probability of having only speech (s0) or only music (m0),
           before considering the new observation. */
@@ -619,24 +891,17 @@
              tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);
              tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);
           }
-       } else {
-          if (tonal->music_confidence_count==0)
-             tonal->music_confidence = .9f;
-          if (tonal->speech_confidence_count==0)
-             tonal->speech_confidence = .1f;
        }
     }
-    if (tonal->last_music != (tonal->music_prob>.5f))
-       tonal->last_transition=0;
     tonal->last_music = tonal->music_prob>.5f;
-#else
-    info->music_prob = 0;
-#endif
-    /*for (i=0;i<25;i++)
+#ifdef MLP_TRAINING
+    for (i=0;i<25;i++)
        printf("%f ", features[i]);
-    printf("\n");*/
+    printf("\n");
+#endif
 
     info->bandwidth = bandwidth;
+    tonal->prev_bandwidth = bandwidth;
     /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
     info->noisiness = frame_noisiness;
     info->valid = 1;
@@ -650,18 +915,19 @@
    int offset;
    int pcm_len;
 
+   analysis_frame_size -= analysis_frame_size&1;
    if (analysis_pcm != NULL)
    {
       /* Avoid overflow/wrap-around of the analysis buffer */
-      analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size);
+      analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/50, analysis_frame_size);
 
       pcm_len = analysis_frame_size - analysis->analysis_offset;
       offset = analysis->analysis_offset;
-      do {
-         tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
-         offset += 480;
-         pcm_len -= 480;
-      } while (pcm_len>0);
+      while (pcm_len>0) {
+         tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(Fs/50, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
+         offset += Fs/50;
+         pcm_len -= Fs/50;
+      }
       analysis->analysis_offset = analysis_frame_size;
 
       analysis->analysis_offset -= frame_size;
@@ -670,3 +936,5 @@
    analysis_info->valid = 0;
    tonality_get_info(analysis, analysis_info, frame_size);
 }
+
+#endif /* DISABLE_FLOAT_API */
diff --git a/src/analysis.h b/src/analysis.h
index 9eae56a..cac51df 100644
--- a/src/analysis.h
+++ b/src/analysis.h
@@ -33,13 +33,20 @@
 
 #define NB_FRAMES 8
 #define NB_TBANDS 18
-#define NB_TOT_BANDS 21
-#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */
+#define ANALYSIS_BUF_SIZE 720 /* 30 ms at 24 kHz */
 
-#define DETECT_SIZE 200
+/* At that point we can stop counting frames because it no longer matters. */
+#define ANALYSIS_COUNT_MAX 10000
+
+#define DETECT_SIZE 100
+
+/* Uncomment this to print the MLP features on stdout. */
+/*#define MLP_TRAINING*/
 
 typedef struct {
    int arch;
+   int application;
+   opus_int32 Fs;
 #define TONALITY_ANALYSIS_RESET_START angle
    float angle[240];
    float d_angle[240];
@@ -48,21 +55,22 @@
    int   mem_fill;                      /* number of usable samples in the buffer */
    float prev_band_tonality[NB_TBANDS];
    float prev_tonality;
+   int prev_bandwidth;
    float E[NB_FRAMES][NB_TBANDS];
+   float logE[NB_FRAMES][NB_TBANDS];
    float lowE[NB_TBANDS];
    float highE[NB_TBANDS];
-   float meanE[NB_TOT_BANDS];
+   float meanE[NB_TBANDS+1];
    float mem[32];
    float cmean[8];
    float std[9];
    float music_prob;
+   float vad_prob;
    float Etracker;
    float lowECount;
    int E_count;
    int last_music;
-   int last_transition;
    int count;
-   float subframe_mem[3];
    int analysis_offset;
    /** Probability of having speech for time i to DETECT_SIZE-1 (and music before).
        pspeech[0] is the probability that all frames in the window are speech. */
@@ -77,6 +85,8 @@
    int write_pos;
    int read_pos;
    int read_subframe;
+   float hp_ener_accum;
+   opus_val32 downmix_state[3];
    AnalysisInfo info[DETECT_SIZE];
 } TonalityAnalysisState;
 
@@ -86,7 +96,7 @@
  * not be repeated every analysis step. No allocated memory is retained
  * by the state struct, so no cleanup call is required.
  */
-void tonality_analysis_init(TonalityAnalysisState *analysis);
+void tonality_analysis_init(TonalityAnalysisState *analysis, opus_int32 Fs);
 
 /** Reset a TonalityAnalysisState stuct.
  *
diff --git a/src/mlp_data.c b/src/mlp_data.c
index c2fda4e..a819880 100644
--- a/src/mlp_data.c
+++ b/src/mlp_data.c
@@ -1,106 +1,109 @@
-/* The contents of this file was automatically generated by mlp_train.c
-   It contains multi-layer perceptron (MLP) weights. */
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "mlp.h"
 
-/* RMS error was 0.138320, seed was 1361535663 */
+/* RMS error was 0.280492, seed was 1480478173 */
+/* 0.005976 0.031821 (0.280494 0.280492) done */
 
-static const float weights[422] = {
+static const float weights[450] = {
 
 /* hidden layer */
--0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f,
--0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f,
--0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f,
-0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f,
-0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f,
-24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f,
--0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f,
--0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f,
--0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f,
-1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f,
-15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f,
-0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f,
--0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f,
-0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f,
-0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f,
--1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f,
--0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f,
--0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f,
-0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f,
--0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f,
-2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f,
-0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f,
--0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f,
-0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f,
-0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f,
--4.60683f, 1.4697f, 0.335845f, -1.81905f, -30.1699f,
-5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f,
--0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f,
--0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f,
--0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f,
-1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f,
--7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f,
--0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f,
-0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f,
-0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f,
--0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f,
-10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f,
--0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f,
--0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f,
--0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f,
-0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f,
--0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f,
-0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f,
-0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f,
--0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f,
-0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f,
--0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f,
--0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f,
--0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f,
--0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f,
--0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f,
-5.8427f, -0.38075f, 0.221894f, -1.41934f, -1.87943e+06f,
-1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f,
-0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f,
--0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f,
-0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f,
--0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f,
--975268.f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f,
-0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f,
--0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f,
--2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f,
-0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f,
--6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f,
-0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f,
--0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f,
--0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f,
-0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f,
--0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f,
-0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f,
--0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f,
-0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f,
--2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f,
-4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f,
-0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f,
--0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f,
-0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f,
-0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f,
-3.95279f, 1.89068f, 0.486087f, -11.3343f, 3.9416e+06f,
-
+-0.514624f, 0.0234227f, -0.14329f, -0.0878216f, -0.00187827f,
+-0.0257443f, 0.108524f, 0.00333881f, 0.00585017f, -0.0246132f,
+0.142723f, -0.00436494f, 0.0101354f, -0.11124f, -0.0809367f,
+-0.0750772f, 0.0295524f, 0.00823944f, 0.150392f, 0.0320876f,
+-0.0710564f, -1.43818f, 0.652076f, 0.0650744f, -1.54821f,
+0.168949f, -1.92724f, 0.0517976f, -0.0670737f, -0.0690121f,
+0.00247528f, -0.0522024f, 0.0631368f, 0.0532776f, 0.047751f,
+-0.011715f, 0.142374f, -0.0290885f, -0.279263f, -0.433499f,
+-0.0795174f, -0.380458f, -0.051263f, 0.218537f, -0.322478f,
+1.06667f, -0.104607f, -4.70108f, 0.312037f, 0.277397f,
+-2.71859f, 1.70037f, -0.141845f, 0.0115618f, 0.0629883f,
+0.0403871f, 0.0139428f, -0.00430733f, -0.0429038f, -0.0590318f,
+-0.0501526f, -0.0284802f, -0.0415686f, -0.0438999f, 0.0822666f,
+0.197194f, 0.0363275f, -0.0584307f, 0.0752364f, -0.0799796f,
+-0.146275f, 0.161661f, -0.184585f, 0.145568f, 0.442823f,
+1.61221f, 1.11162f, 2.62177f, -2.482f, -0.112599f,
+-0.110366f, -0.140794f, -0.181694f, 0.0648674f, 0.0842248f,
+0.0933993f, 0.150122f, 0.129171f, 0.176848f, 0.141758f,
+-0.271822f, 0.235113f, 0.0668579f, -0.433957f, 0.113633f,
+-0.169348f, -1.40091f, 0.62861f, -0.134236f, 0.402173f,
+1.86373f, 1.53998f, -4.32084f, 0.735343f, 0.800214f,
+-0.00968415f, 0.0425904f, 0.0196811f, -0.018426f, -0.000343953f,
+-0.00416389f, 0.00111558f, 0.0173069f, -0.00998596f, -0.025898f,
+0.00123764f, -0.00520373f, -0.0565033f, 0.0637394f, 0.0051213f,
+0.0221361f, 0.00819962f, -0.0467061f, -0.0548258f, -0.00314063f,
+-1.18332f, 1.88091f, -0.41148f, -2.95727f, -0.521449f,
+-0.271641f, 0.124946f, -0.0532936f, 0.101515f, 0.000208564f,
+-0.0488748f, 0.0642388f, -0.0383848f, 0.0135046f, -0.0413592f,
+-0.0326402f, -0.0137421f, -0.0225219f, -0.0917294f, -0.277759f,
+-0.185418f, 0.0471128f, -0.125879f, 0.262467f, -0.212794f,
+-0.112931f, -1.99885f, -0.404787f, 0.224402f, 0.637962f,
+-0.27808f, -0.0723953f, -0.0537655f, -0.0336359f, -0.0906601f,
+-0.0641309f, -0.0713542f, 0.0524317f, 0.00608819f, 0.0754101f,
+-0.0488401f, -0.00671865f, 0.0418239f, 0.0536284f, -0.132639f,
+0.0267648f, -0.248432f, -0.0104153f, 0.035544f, -0.212753f,
+-0.302895f, -0.0357854f, 0.376838f, 0.597025f, -0.664647f,
+0.268422f, -0.376772f, -1.05472f, 0.0144178f, 0.179122f,
+0.0360155f, 0.220262f, -0.0056381f, 0.0317197f, 0.0621066f,
+-0.00779298f, 0.00789378f, 0.00350605f, 0.0104809f, 0.0362871f,
+-0.157708f, -0.0659779f, -0.0926278f, 0.00770791f, 0.0631621f,
+0.0817343f, -0.424295f, -0.0437727f, -0.24251f, 0.711217f,
+-0.736455f, -2.194f, -0.107612f, -0.175156f, -0.0366573f,
+-0.0123156f, -0.0628516f, -0.0218977f, -0.00693699f, 0.00695185f,
+0.00507362f, 0.00359334f, 0.0052661f, 0.035561f, 0.0382701f,
+0.0342179f, -0.00790271f, -0.0170925f, 0.047029f, 0.0197362f,
+-0.0153435f, 0.0644152f, -0.36862f, -0.0674876f, -2.82672f,
+1.34122f, -0.0788029f, -3.47792f, 0.507246f, -0.816378f,
+-0.0142383f, -0.127349f, -0.106926f, -0.0359524f, 0.105045f,
+0.291554f, 0.195413f, 0.0866214f, -0.066577f, -0.102188f,
+0.0979466f, -0.12982f, 0.400181f, -0.409336f, -0.0593326f,
+-0.0656203f, -0.204474f, 0.179802f, 0.000509084f, 0.0995954f,
+-2.377f, -0.686359f, 0.934861f, 1.10261f, 1.3901f,
+-4.33616f, -0.00264017f, 0.00713045f, 0.106264f, 0.143726f,
+-0.0685305f, -0.054656f, -0.0176725f, -0.0772669f, -0.0264526f,
+-0.0103824f, -0.0269872f, -0.00687f, 0.225804f, 0.407751f,
+-0.0612611f, -0.0576863f, -0.180131f, -0.222772f, -0.461742f,
+0.335236f, 1.03399f, 4.24112f, -0.345796f, -0.594549f,
+-76.1407f, -0.265276f, 0.0507719f, 0.0643044f, 0.0384832f,
+0.0424459f, -0.0387817f, -0.0235996f, -0.0740556f, -0.0270029f,
+0.00882177f, -0.0552371f, -0.00485851f, 0.314295f, 0.360431f,
+-0.0787085f, 0.110355f, -0.415958f, -0.385088f, -0.272224f,
+-1.55108f, -0.141848f, 0.448877f, -0.563447f, -2.31403f,
+-0.120077f, -1.49918f, -0.817726f, -0.0495854f, -0.0230782f,
+-0.0224014f, 0.117076f, 0.0393216f, 0.051997f, 0.0330763f,
+-0.110796f, 0.0211117f, -0.0197258f, 0.0187461f, 0.0125183f,
+0.14876f, 0.0920565f, -0.342475f, 0.135272f, -0.168155f,
+-0.033423f, -0.0604611f, -0.128835f, 0.664947f, -0.144997f,
+2.27649f, 1.28663f, 0.841217f, -2.42807f, 0.0230471f,
+0.226709f, -0.0374803f, 0.155436f, 0.0400342f, -0.184686f,
+0.128488f, -0.0939518f, -0.0578559f, 0.0265967f, -0.0999322f,
+-0.0322768f, -0.322994f, -0.189371f, -0.738069f, -0.0754914f,
+0.214717f, -0.093728f, -0.695741f, 0.0899298f, -2.06188f,
+-0.273719f, -0.896977f, 0.130553f, 0.134638f, 1.29355f,
+0.00520749f, -0.0324224f, 0.00530451f, 0.0192385f, 0.00328708f,
+0.0250838f, 0.0053365f, -0.0177321f, 0.00618789f, 0.00525364f,
+0.00104596f, -0.0360459f, 0.0402403f, -0.0406351f, 0.0136883f,
+0.0880722f, -0.0197449f, 0.089938f, 0.0100456f, -0.0475638f,
+-0.73267f, 0.037433f, -0.146551f, -0.230221f, -3.06489f,
+-1.40194f, 0.0198483f, 0.0397953f, -0.0190239f, 0.0470715f,
+-0.131363f, -0.191721f, -0.0176224f, -0.0480352f, -0.221799f,
+-0.26794f, -0.0292615f, 0.0612127f, -0.129877f, 0.00628332f,
+-0.085918f, 0.0175379f, 0.0541011f, -0.0810874f, -0.380809f,
+-0.222056f, -0.508859f, -0.473369f, 0.484958f, -2.28411f,
+0.0139516f,
 /* output layer */
--0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f,
-0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f,
-0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f,
-0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f,
-4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f,
--1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f,
-3.87308f, 3.52558f};
+3.90017f, 1.71789f, -1.43372f, -2.70839f, 1.77107f,
+5.48006f, 1.44661f, 2.01134f, -1.88383f, -3.64958f,
+-1.26351f, 0.779421f, 2.11357f, 3.10409f, 1.68846f,
+-4.46197f, -1.61455f, 3.59832f, 2.43531f, -1.26458f,
+0.417941f, 1.47437f, 2.16635f, -1.909f, -0.828869f,
+1.38805f, -2.67975f, -0.110044f, 1.95596f, 0.697931f,
+-0.313226f, -0.889315f, 0.283236f, 0.946102f, };
 
-static const int topo[3] = {25, 15, 2};
+static const int topo[3] = {25, 16, 2};
 
 const MLP net = {
     3,
diff --git a/src/mlp_train.c b/src/mlp_train.c
index e02fea9..8d9d127 100644
--- a/src/mlp_train.c
+++ b/src/mlp_train.c
@@ -138,13 +138,16 @@
     for (s=0;s<nbSamples;s++)
     {
         float *in, *out;
+        float inp[inDim];
         in = inputs+s*inDim;
         out = outputs + s*outDim;
+        for (j=0;j<inDim;j++)
+           inp[j] = in[j];
         for (i=0;i<hiddenDim;i++)
         {
             double sum = W0[i*(inDim+1)];
             for (j=0;j<inDim;j++)
-                sum += W0[i*(inDim+1)+j+1]*in[j];
+                sum += W0[i*(inDim+1)+j+1]*inp[j];
             hidden[i] = tansig_approx(sum);
         }
         for (i=0;i<outDim;i++)
@@ -154,14 +157,16 @@
                 sum += W1[i*(hiddenDim+1)+j+1]*hidden[j];
             netOut[i] = tansig_approx(sum);
             error[i] = out[i] - netOut[i];
-            rms += error[i]*error[i];
+            if (out[i] == 0) error[i] *= .0;
             error_rate[i] += fabs(error[i])>1;
+            if (i==0) error[i] *= 5;
+            rms += error[i]*error[i];
             /*error[i] = error[i]/(1+fabs(error[i]));*/
         }
         /* Back-propagate error */
         for (i=0;i<outDim;i++)
         {
-            float grad = 1-netOut[i]*netOut[i];
+            double grad = 1-netOut[i]*netOut[i];
             W1_grad[i*(hiddenDim+1)] += error[i]*grad;
             for (j=0;j<hiddenDim;j++)
                 W1_grad[i*(hiddenDim+1)+j+1] += grad*error[i]*hidden[j];
@@ -175,7 +180,7 @@
             grad *= 1-hidden[i]*hidden[i];
             W0_grad[i*(inDim+1)] += grad;
             for (j=0;j<inDim;j++)
-                W0_grad[i*(inDim+1)+j+1] += grad*in[j];
+                W0_grad[i*(inDim+1)+j+1] += grad*inp[j];
         }
     }
     return rms;
@@ -230,8 +235,6 @@
     int inDim, outDim, hiddenDim;
     int *topo;
     double *W0, *W1, *best_W0, *best_W1;
-    double *W0_old, *W1_old;
-    double *W0_old2, *W1_old2;
     double *W0_grad, *W1_grad;
     double *W0_oldgrad, *W1_oldgrad;
     double *W0_rate, *W1_rate;
@@ -254,10 +257,6 @@
     W1 = net->weights[1];
     best_W0 = net->best_weights[0];
     best_W1 = net->best_weights[1];
-    W0_old = malloc(W0_size*sizeof(double));
-    W1_old = malloc(W1_size*sizeof(double));
-    W0_old2 = malloc(W0_size*sizeof(double));
-    W1_old2 = malloc(W1_size*sizeof(double));
     W0_grad = malloc(W0_size*sizeof(double));
     W1_grad = malloc(W1_size*sizeof(double));
     W0_oldgrad = malloc(W0_size*sizeof(double));
@@ -266,12 +265,8 @@
     W1_rate = malloc(W1_size*sizeof(double));
     best_W0_rate = malloc(W0_size*sizeof(double));
     best_W1_rate = malloc(W1_size*sizeof(double));
-    memcpy(W0_old, W0, W0_size*sizeof(double));
-    memcpy(W0_old2, W0, W0_size*sizeof(double));
     memset(W0_grad, 0, W0_size*sizeof(double));
     memset(W0_oldgrad, 0, W0_size*sizeof(double));
-    memcpy(W1_old, W1, W1_size*sizeof(double));
-    memcpy(W1_old2, W1, W1_size*sizeof(double));
     memset(W1_grad, 0, W1_size*sizeof(double));
     memset(W1_oldgrad, 0, W1_size*sizeof(double));
 
@@ -376,8 +371,6 @@
             /*if (W0_rate[i] > .01)
                 W0_rate[i] = .01;*/
             W0_oldgrad[i] = W0_grad[i];
-            W0_old2[i] = W0_old[i];
-            W0_old[i] = W0[i];
             W0[i] += W0_grad[i]*W0_rate[i];
         }
         for (i=0;i<W1_size;i++)
@@ -392,8 +385,6 @@
             if (W1_rate[i] < 1e-15)
                 W1_rate[i] = 1e-15;
             W1_oldgrad[i] = W1_grad[i];
-            W1_old2[i] = W1_old[i];
-            W1_old[i] = W1[i];
             W1[i] += W1_grad[i]*W1_rate[i];
         }
         mean_rate /= (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2];
@@ -411,12 +402,14 @@
         pthread_join(thread[i], NULL);
         fprintf (stderr, "joined %d\n", i);
     }
-    free(W0_old);
-    free(W1_old);
     free(W0_grad);
+    free(W0_oldgrad);
     free(W1_grad);
+    free(W1_oldgrad);
     free(W0_rate);
+    free(best_W0_rate);
     free(W1_rate);
+    free(best_W1_rate);
     return best_rms;
 }
 
@@ -449,7 +442,7 @@
     outputs = malloc(nbOutputs*nbSamples*sizeof(*outputs));
 
     seed = time(NULL);
-    /*seed = 1361480659;*/
+    /*seed = 1452209040;*/
     fprintf (stderr, "Seed is %u\n", seed);
     srand(seed);
     build_tansig_table();
@@ -474,28 +467,35 @@
     fprintf (stderr, "Got %d samples\n", nbSamples);
     net = mlp_init(topo, 3, inputs, outputs, nbSamples);
     rms = mlp_train_backprop(net, inputs, outputs, nbSamples, nbEpoch, 1);
+    printf ("#ifdef HAVE_CONFIG_H\n");
+    printf ("#include \"config.h\"\n");
+    printf ("#endif\n\n");
     printf ("#include \"mlp.h\"\n\n");
     printf ("/* RMS error was %f, seed was %u */\n\n", rms, seed);
     printf ("static const float weights[%d] = {\n", (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2]);
     printf ("\n/* hidden layer */\n");
     for (i=0;i<(topo[0]+1)*topo[1];i++)
     {
-        printf ("%gf, ", net->weights[0][i]);
+        printf ("%gf,", net->weights[0][i]);
         if (i%5==4)
             printf("\n");
+        else
+            printf(" ");
     }
     printf ("\n/* output layer */\n");
     for (i=0;i<(topo[1]+1)*topo[2];i++)
     {
-        printf ("%g, ", net->weights[1][i]);
+        printf ("%gf,", net->weights[1][i]);
         if (i%5==4)
             printf("\n");
+        else
+            printf(" ");
     }
     printf ("};\n\n");
     printf ("static const int topo[3] = {%d, %d, %d};\n\n", topo[0], topo[1], topo[2]);
     printf ("const MLP net = {\n");
-    printf ("\t3,\n");
-    printf ("\ttopo,\n");
-    printf ("\tweights\n};\n");
+    printf ("    3,\n");
+    printf ("    topo,\n");
+    printf ("    weights\n};\n");
     return 0;
 }
diff --git a/src/mlp_train.h b/src/mlp_train.h
index 2786b40..4940415 100644
--- a/src/mlp_train.h
+++ b/src/mlp_train.h
@@ -36,7 +36,7 @@
 {
     return 2./(1.+exp(-2.*x)) - 1.;
 }
-static inline void build_tansig_table()
+static inline void build_tansig_table(void)
 {
     int i;
     for (i=0;i<501;i++)
@@ -59,7 +59,7 @@
     return y;
 }
 
-inline float randn(float sd)
+static inline float randn(float sd)
 {
    float U1, U2, S, x;
    do {
diff --git a/src/opus.c b/src/opus.c
index f76f125..cdbd13a 100644
--- a/src/opus.c
+++ b/src/opus.c
@@ -107,7 +107,7 @@
          /* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math
             does not cause output values larger than +/-1, but small enough not
             to matter even for 24-bit output.  */
-         a += a*2.4e-7;
+         a += a*2.4e-7f;
          if (x[i*C]>0)
             a = -a;
          /* Apply soft clipping */
diff --git a/src/opus_compare.c b/src/opus_compare.c
index 06c67d7..1956e08 100644
--- a/src/opus_compare.c
+++ b/src/opus_compare.c
@@ -363,6 +363,9 @@
     Ef*=Ef;
     err+=Ef*Ef;
   }
+  free(xb);
+  free(X);
+  free(Y);
   err=pow(err/nframes,1.0/16);
   Q=100*(1-0.5*log(1+err)/log(1.13));
   if(Q<0){
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 080bec5..149ae7f 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -891,7 +891,7 @@
    break;
    case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
    {
-      opus_uint32 *value = va_arg(ap, opus_uint32*);
+      opus_int32 *value = va_arg(ap, opus_int32*);
       if (!value)
       {
          goto bad_arg;
@@ -899,6 +899,26 @@
       *value = st->last_packet_duration;
    }
    break;
+   case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
+   {
+       opus_int32 value = va_arg(ap, opus_int32);
+       if(value<0 || value>1)
+       {
+          goto bad_arg;
+       }
+       celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
+   }
+   break;
+   case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
+   {
+       opus_int32 *value = va_arg(ap, opus_int32*);
+       if (!value)
+       {
+          goto bad_arg;
+       }
+       celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
+   }
+   break;
    default:
       /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
       ret = OPUS_UNIMPLEMENTED;
diff --git a/src/opus_demo.c b/src/opus_demo.c
index 7c93069..50987c9 100644
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -54,9 +54,9 @@
     fprintf(stderr, "-d                   : only runs the decoder (reads the bit-stream as input)\n" );
     fprintf(stderr, "-cbr                 : enable constant bitrate; default: variable bitrate\n" );
     fprintf(stderr, "-cvbr                : enable constrained variable bitrate; default: unconstrained\n" );
-    fprintf(stderr, "-variable-duration   : enable frames of variable duration (experts only); default: disabled\n" );
+    fprintf(stderr, "-delayed-decision    : use look-ahead for speech/music detection (experts only); default: disabled\n" );
     fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
-    fprintf(stderr, "-framesize <2.5|5|10|20|40|60> : frame size in ms; default: 20 \n" );
+    fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" );
     fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
     fprintf(stderr, "-complexity <comp>   : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
     fprintf(stderr, "-inbandfec           : enable SILK inband FEC\n" );
@@ -253,6 +253,7 @@
     opus_uint32 dec_final_range;
     int encode_only=0, decode_only=0;
     int max_frame_size = 48000*2;
+    size_t num_read;
     int curr_read=0;
     int sweep_bps = 0;
     int random_framesize=0, newsize=0, delayed_celt=0;
@@ -382,9 +383,15 @@
                 frame_size = sampling_rate/25;
             else if (strcmp(argv[ args + 1 ], "60")==0)
                 frame_size = 3*sampling_rate/50;
+            else if (strcmp(argv[ args + 1 ], "80")==0)
+                frame_size = 4*sampling_rate/50;
+            else if (strcmp(argv[ args + 1 ], "100")==0)
+                frame_size = 5*sampling_rate/50;
+            else if (strcmp(argv[ args + 1 ], "120")==0)
+                frame_size = 6*sampling_rate/50;
             else {
                 fprintf(stderr, "Unsupported frame size: %s ms. "
-                                "Supported are 2.5, 5, 10, 20, 40, 60.\n",
+                                "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n",
                                 argv[ args + 1 ]);
                 return EXIT_FAILURE;
             }
@@ -408,10 +415,6 @@
             check_encoder_option(decode_only, "-cvbr");
             cvbr = 1;
             args++;
-        } else if( strcmp( argv[ args ], "-variable-duration" ) == 0 ) {
-            check_encoder_option(decode_only, "-variable-duration");
-            variable_duration = OPUS_FRAMESIZE_VARIABLE;
-            args++;
         } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
             check_encoder_option(decode_only, "-delayed-decision");
             delayed_decision = 1;
@@ -599,22 +602,25 @@
     }
     if(delayed_decision)
     {
-       if (variable_duration!=OPUS_FRAMESIZE_VARIABLE)
-       {
-          if (frame_size==sampling_rate/400)
-             variable_duration = OPUS_FRAMESIZE_2_5_MS;
-          else if (frame_size==sampling_rate/200)
-             variable_duration = OPUS_FRAMESIZE_5_MS;
-          else if (frame_size==sampling_rate/100)
-             variable_duration = OPUS_FRAMESIZE_10_MS;
-          else if (frame_size==sampling_rate/50)
-             variable_duration = OPUS_FRAMESIZE_20_MS;
-          else if (frame_size==sampling_rate/25)
-             variable_duration = OPUS_FRAMESIZE_40_MS;
-          else
-             variable_duration = OPUS_FRAMESIZE_60_MS;
-          opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
-       }
+       if (frame_size==sampling_rate/400)
+          variable_duration = OPUS_FRAMESIZE_2_5_MS;
+       else if (frame_size==sampling_rate/200)
+          variable_duration = OPUS_FRAMESIZE_5_MS;
+       else if (frame_size==sampling_rate/100)
+          variable_duration = OPUS_FRAMESIZE_10_MS;
+       else if (frame_size==sampling_rate/50)
+          variable_duration = OPUS_FRAMESIZE_20_MS;
+       else if (frame_size==sampling_rate/25)
+          variable_duration = OPUS_FRAMESIZE_40_MS;
+       else if (frame_size==3*sampling_rate/50)
+          variable_duration = OPUS_FRAMESIZE_60_MS;
+       else if (frame_size==4*sampling_rate/50)
+          variable_duration = OPUS_FRAMESIZE_80_MS;
+       else if (frame_size==5*sampling_rate/50)
+          variable_duration = OPUS_FRAMESIZE_100_MS;
+       else
+          variable_duration = OPUS_FRAMESIZE_120_MS;
+       opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
        frame_size = 2*48000;
     }
     while (!stop)
@@ -652,8 +658,8 @@
         if (decode_only)
         {
             unsigned char ch[4];
-            err = fread(ch, 1, 4, fin);
-            if (feof(fin))
+            num_read = fread(ch, 1, 4, fin);
+            if (num_read!=4)
                 break;
             len[toggle] = char_to_int(ch);
             if (len[toggle]>max_payload_bytes || len[toggle]<0)
@@ -661,14 +667,16 @@
                 fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
                 break;
             }
-            err = fread(ch, 1, 4, fin);
+            num_read = fread(ch, 1, 4, fin);
+            if (num_read!=4)
+                break;
             enc_final_range[toggle] = char_to_int(ch);
-            err = fread(data[toggle], 1, len[toggle], fin);
-            if (err<len[toggle])
+            num_read = fread(data[toggle], 1, len[toggle], fin);
+            if (num_read!=(size_t)len[toggle])
             {
                 fprintf(stderr, "Ran out of input, "
                                 "expecting %d bytes got %d\n",
-                                len[toggle],err);
+                                len[toggle],(int)num_read);
                 break;
             }
         } else {
@@ -680,8 +688,8 @@
                 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
                 frame_size = mode_list[curr_mode][2];
             }
-            err = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
-            curr_read = err;
+            num_read = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
+            curr_read = (int)num_read;
             tot_in += curr_read;
             for(i=0;i<curr_read*channels;i++)
             {
@@ -764,7 +772,7 @@
             }
             tot_samples += nb_encoded;
         } else {
-            int output_samples;
+            opus_int32 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));
@@ -790,7 +798,7 @@
                     if (!decode_only && tot_out + output_samples > tot_in)
                     {
                        stop=1;
-                       output_samples  = tot_in-tot_out;
+                       output_samples = (opus_int32)(tot_in - tot_out);
                     }
                     if (output_samples>skip) {
                        int i;
@@ -870,8 +878,6 @@
                1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act));
     fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
             1e-3*sqrt(bits2/count - bits*bits/(count*(double)count))*sampling_rate/frame_size);
-    /* Close any files to which intermediate results were stored */
-    SILK_DEBUG_STORE_CLOSE_FILES
     silk_TimerSave("opus_timing.txt");
     opus_encoder_destroy(enc);
     opus_decoder_destroy(dec);
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 9a516a8..474e6c2 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -53,6 +53,10 @@
 
 #define MAX_ENCODER_BUFFER 480
 
+#ifndef DISABLE_FLOAT_API
+#define PSEUDO_SNR_THRESHOLD 316.23f    /* 10^(25/10) */
+#endif
+
 typedef struct {
    opus_val32 XX, XY, YY;
    opus_val16 smoothed_width;
@@ -82,6 +86,7 @@
     int          encoder_buffer;
     int          lfe;
     int          arch;
+    int          use_dtx;                 /* general DTX for both SILK and CELT */
 #ifndef DISABLE_FLOAT_API
     TonalityAnalysisState analysis;
 #endif
@@ -97,6 +102,8 @@
     int          prev_channels;
     int          prev_framesize;
     int          bandwidth;
+    /* Bandwidth determined automatically from the rate (before any other adjustment) */
+    int          auto_bandwidth;
     int          silk_bw_switch;
     /* Sampling rate (at the API level) */
     int          first;
@@ -105,7 +112,10 @@
     opus_val16   delay_buffer[MAX_ENCODER_BUFFER*2];
 #ifndef DISABLE_FLOAT_API
     int          detected_bandwidth;
+    int          nb_no_activity_frames;
+    opus_val32   peak_signal_energy;
 #endif
+    int          nonfinal_frame; /* current frame is not the final in a packet */
     opus_uint32  rangeFinal;
 };
 
@@ -113,32 +123,32 @@
    middle (memoriless) threshold. The second column is the hysteresis
    (difference with the middle) */
 static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
-        11000, 1000, /* NB<->MB */
-        14000, 1000, /* MB<->WB */
-        17000, 1000, /* WB<->SWB */
-        21000, 2000, /* SWB<->FB */
+        10000, 1000, /* NB<->MB */
+        11000, 1000, /* MB<->WB */
+        13500, 1000, /* WB<->SWB */
+        14000, 2000, /* SWB<->FB */
 };
 static const opus_int32 mono_music_bandwidth_thresholds[8] = {
-        12000, 1000, /* NB<->MB */
-        15000, 1000, /* MB<->WB */
-        18000, 2000, /* WB<->SWB */
-        22000, 2000, /* SWB<->FB */
+        10000, 1000, /* NB<->MB */
+        11000, 1000, /* MB<->WB */
+        13500, 1000, /* WB<->SWB */
+        14000, 2000, /* SWB<->FB */
 };
 static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
-        11000, 1000, /* NB<->MB */
-        14000, 1000, /* MB<->WB */
-        21000, 2000, /* WB<->SWB */
-        28000, 2000, /* SWB<->FB */
+        10000, 1000, /* NB<->MB */
+        11000, 1000, /* MB<->WB */
+        13500, 1000, /* WB<->SWB */
+        14000, 2000, /* SWB<->FB */
 };
 static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
-        12000, 1000, /* NB<->MB */
-        18000, 2000, /* MB<->WB */
-        21000, 2000, /* WB<->SWB */
-        30000, 2000, /* SWB<->FB */
+        10000, 1000, /* NB<->MB */
+        11000, 1000, /* MB<->WB */
+        13500, 1000, /* WB<->SWB */
+        14000, 2000, /* SWB<->FB */
 };
 /* Threshold bit-rates for switching between mono and stereo */
-static const opus_int32 stereo_voice_threshold = 30000;
-static const opus_int32 stereo_music_threshold = 30000;
+static const opus_int32 stereo_voice_threshold = 24000;
+static const opus_int32 stereo_music_threshold = 24000;
 
 /* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
 static const opus_int32 mode_thresholds[2][2] = {
@@ -147,6 +157,14 @@
       {  36000,      16000}, /* stereo */
 };
 
+static const opus_int32 fec_thresholds[] = {
+        12000, 1000, /* NB */
+        14000, 1000, /* MB */
+        16000, 1000, /* WB */
+        20000, 1000, /* SWB */
+        22000, 1000, /* FB */
+};
+
 int opus_encoder_get_size(int channels)
 {
     int silkEncSizeBytes, celtEncSizeBytes;
@@ -245,7 +263,8 @@
     st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
 
 #ifndef DISABLE_FLOAT_API
-    tonality_analysis_init(&st->analysis);
+    tonality_analysis_init(&st->analysis, st->Fs);
+    st->analysis.application = st->application;
 #endif
 
     return OPUS_OK;
@@ -323,10 +342,11 @@
 }
 #endif
 
-static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
+static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs, int arch)
 {
    opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
    opus_int32 Fc_Q19, r_Q28, r_Q22;
+   (void)arch;
 
    silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );
    Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );
@@ -346,9 +366,10 @@
    A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
 
 #ifdef FIXED_POINT
-   silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels );
-   if( channels == 2 ) {
-       silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
+   if( channels == 1 ) {
+      silk_biquad_alt_stride1( in, B_Q28, A_Q28, hp_mem, out, len );
+   } else {
+      silk_biquad_alt_stride2( in, B_Q28, A_Q28, hp_mem, out, len, arch );
    }
 #else
    silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
@@ -371,14 +392,14 @@
       for (i=0;i<len;i++)
       {
          opus_val32 x, tmp, y;
-         x = SHL32(EXTEND32(in[channels*i+c]), 15);
+         x = SHL32(EXTEND32(in[channels*i+c]), 14);
          /* First stage */
          tmp = x-hp_mem[2*c];
          hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);
          /* Second stage */
          y = tmp - hp_mem[2*c+1];
          hp_mem[2*c+1] = hp_mem[2*c+1] + PSHR32(tmp - hp_mem[2*c+1], shift);
-         out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 15), 32767));
+         out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 14), 32767));
       }
    }
 }
@@ -386,24 +407,57 @@
 #else
 static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
 {
-   int c, i;
-   float coef;
-
+   int i;
+   float coef, coef2;
    coef = 4.0f*cutoff_Hz/Fs;
-   for (c=0;c<channels;c++)
+   coef2 = 1-coef;
+   if (channels==2)
    {
+      float m0, m1, m2, m3;
+      m0 = hp_mem[0];
+      m1 = hp_mem[1];
+      m2 = hp_mem[2];
+      m3 = hp_mem[3];
+      for (i=0;i<len;i++)
+      {
+         opus_val32 x0, x1, tmp0, tmp1, out0, out1;
+         x0 = in[2*i+0];
+         x1 = in[2*i+1];
+         /* First stage */
+         tmp0 = x0-m0;
+         tmp1 = x1-m2;
+         m0 = coef*x0 + VERY_SMALL + coef2*m0;
+         m2 = coef*x1 + VERY_SMALL + coef2*m2;
+         /* Second stage */
+         out0 = tmp0 - m1;
+         out1 = tmp1 - m3;
+         m1 = coef*tmp0 + VERY_SMALL + coef2*m1;
+         m3 = coef*tmp1 + VERY_SMALL + coef2*m3;
+         out[2*i+0] = out0;
+         out[2*i+1] = out1;
+      }
+      hp_mem[0] = m0;
+      hp_mem[1] = m1;
+      hp_mem[2] = m2;
+      hp_mem[3] = m3;
+   } else {
+      float m0, m1;
+      m0 = hp_mem[0];
+      m1 = hp_mem[1];
       for (i=0;i<len;i++)
       {
          opus_val32 x, tmp, y;
-         x = in[channels*i+c];
+         x = in[i];
          /* First stage */
-         tmp = x-hp_mem[2*c];
-         hp_mem[2*c] = hp_mem[2*c] + coef*(x - hp_mem[2*c]) + VERY_SMALL;
+         tmp = x-m0;
+         m0 = coef*x + VERY_SMALL + coef2*m0;
          /* Second stage */
-         y = tmp - hp_mem[2*c+1];
-         hp_mem[2*c+1] = hp_mem[2*c+1] + coef*(tmp - hp_mem[2*c+1]) + VERY_SMALL;
-         out[channels*i+c] = y;
+         y = tmp - m1;
+         m1 = coef*tmp + VERY_SMALL + coef2*m1;
+         out[i] = y;
       }
+      hp_mem[0] = m0;
+      hp_mem[1] = m1;
    }
 }
 #endif
@@ -521,287 +575,57 @@
 }
 
 #ifndef DISABLE_FLOAT_API
-/* Don't use more than 60 ms for the frame size analysis */
-#define MAX_DYNAMIC_FRAMESIZE 24
-/* Estimates how much the bitrate will be boosted based on the sub-frame energy */
-static float transient_boost(const float *E, const float *E_1, int LM, int maxM)
-{
-   int i;
-   int M;
-   float sumE=0, sumE_1=0;
-   float metric;
-
-   M = IMIN(maxM, (1<<LM)+1);
-   for (i=0;i<M;i++)
-   {
-      sumE += E[i];
-      sumE_1 += E_1[i];
-   }
-   metric = sumE*sumE_1/(M*M);
-   /*if (LM==3)
-      printf("%f\n", metric);*/
-   /*return metric>10 ? 1 : 0;*/
-   /*return MAX16(0,1-exp(-.25*(metric-2.)));*/
-   return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2))));
-}
-
-/* Viterbi decoding trying to find the best frame size combination using look-ahead
-
-   State numbering:
-    0: unused
-    1:  2.5 ms
-    2:  5 ms (#1)
-    3:  5 ms (#2)
-    4: 10 ms (#1)
-    5: 10 ms (#2)
-    6: 10 ms (#3)
-    7: 10 ms (#4)
-    8: 20 ms (#1)
-    9: 20 ms (#2)
-   10: 20 ms (#3)
-   11: 20 ms (#4)
-   12: 20 ms (#5)
-   13: 20 ms (#6)
-   14: 20 ms (#7)
-   15: 20 ms (#8)
-*/
-static int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate)
-{
-   int i;
-   float cost[MAX_DYNAMIC_FRAMESIZE][16];
-   int states[MAX_DYNAMIC_FRAMESIZE][16];
-   float best_cost;
-   int best_state;
-   float factor;
-   /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */
-   if (rate<80)
-      factor=0;
-   else if (rate>160)
-      factor=1;
-   else
-      factor = (rate-80.f)/80.f;
-   /* Makes variable framesize less aggressive at lower bitrates, but I can't
-      find any valid theoretical justification for this (other than it seems
-      to help) */
-   for (i=0;i<16;i++)
-   {
-      /* Impossible state */
-      states[0][i] = -1;
-      cost[0][i] = 1e10;
-   }
-   for (i=0;i<4;i++)
-   {
-      cost[0][1<<i] = (frame_cost + rate*(1<<i))*(1+factor*transient_boost(E, E_1, i, N+1));
-      states[0][1<<i] = i;
-   }
-   for (i=1;i<N;i++)
-   {
-      int j;
-
-      /* Follow continuations */
-      for (j=2;j<16;j++)
-      {
-         cost[i][j] = cost[i-1][j-1];
-         states[i][j] = j-1;
-      }
-
-      /* New frames */
-      for(j=0;j<4;j++)
-      {
-         int k;
-         float min_cost;
-         float curr_cost;
-         states[i][1<<j] = 1;
-         min_cost = cost[i-1][1];
-         for(k=1;k<4;k++)
-         {
-            float tmp = cost[i-1][(1<<(k+1))-1];
-            if (tmp < min_cost)
-            {
-               states[i][1<<j] = (1<<(k+1))-1;
-               min_cost = tmp;
-            }
-         }
-         curr_cost = (frame_cost + rate*(1<<j))*(1+factor*transient_boost(E+i, E_1+i, j, N-i+1));
-         cost[i][1<<j] = min_cost;
-         /* If part of the frame is outside the analysis window, only count part of the cost */
-         if (N-i < (1<<j))
-            cost[i][1<<j] += curr_cost*(float)(N-i)/(1<<j);
-         else
-            cost[i][1<<j] += curr_cost;
-      }
-   }
-
-   best_state=1;
-   best_cost = cost[N-1][1];
-   /* Find best end state (doesn't force a frame to end at N-1) */
-   for (i=2;i<16;i++)
-   {
-      if (cost[N-1][i]<best_cost)
-      {
-         best_cost = cost[N-1][i];
-         best_state = i;
-      }
-   }
-
-   /* Follow transitions back */
-   for (i=N-1;i>=0;i--)
-   {
-      /*printf("%d ", best_state);*/
-      best_state = states[i][best_state];
-   }
-   /*printf("%d\n", best_state);*/
-   return best_state;
-}
-
-static int optimize_framesize(const void *x, int len, int C, opus_int32 Fs,
-                int bitrate, opus_val16 tonality, float *mem, int buffering,
-                downmix_func downmix)
-{
-   int N;
-   int i;
-   float e[MAX_DYNAMIC_FRAMESIZE+4];
-   float e_1[MAX_DYNAMIC_FRAMESIZE+3];
-   opus_val32 memx;
-   int bestLM=0;
-   int subframe;
-   int pos;
-   int offset;
-   VARDECL(opus_val32, sub);
-
-   subframe = Fs/400;
-   ALLOC(sub, subframe, opus_val32);
-   e[0]=mem[0];
-   e_1[0]=1.f/(EPSILON+mem[0]);
-   if (buffering)
-   {
-      /* Consider the CELT delay when not in restricted-lowdelay */
-      /* We assume the buffering is between 2.5 and 5 ms */
-      offset = 2*subframe - buffering;
-      celt_assert(offset>=0 && offset <= subframe);
-      len -= offset;
-      e[1]=mem[1];
-      e_1[1]=1.f/(EPSILON+mem[1]);
-      e[2]=mem[2];
-      e_1[2]=1.f/(EPSILON+mem[2]);
-      pos = 3;
-   } else {
-      pos=1;
-      offset=0;
-   }
-   N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);
-   /* Just silencing a warning, it's really initialized later */
-   memx = 0;
-   for (i=0;i<N;i++)
-   {
-      float tmp;
-      opus_val32 tmpx;
-      int j;
-      tmp=EPSILON;
-
-      downmix(x, sub, subframe, i*subframe+offset, 0, -2, C);
-      if (i==0)
-         memx = sub[0];
-      for (j=0;j<subframe;j++)
-      {
-         tmpx = sub[j];
-         tmp += (tmpx-memx)*(float)(tmpx-memx);
-         memx = tmpx;
-      }
-      e[i+pos] = tmp;
-      e_1[i+pos] = 1.f/tmp;
-   }
-   /* Hack to get 20 ms working with APPLICATION_AUDIO
-      The real problem is that the corresponding memory needs to use 1.5 ms
-      from this frame and 1 ms from the next frame */
-   e[i+pos] = e[i+pos-1];
-   if (buffering)
-      N=IMIN(MAX_DYNAMIC_FRAMESIZE, N+2);
-   bestLM = transient_viterbi(e, e_1, N, (int)((1.f+.5f*tonality)*(60*C+40)), bitrate/400);
-   mem[0] = e[1<<bestLM];
-   if (buffering)
-   {
-      mem[1] = e[(1<<bestLM)+1];
-      mem[2] = e[(1<<bestLM)+2];
-   }
-   return bestLM;
-}
-
-#endif
-
-#ifndef DISABLE_FLOAT_API
 #ifdef FIXED_POINT
 #define PCM2VAL(x) FLOAT2INT16(x)
 #else
 #define PCM2VAL(x) SCALEIN(x)
 #endif
-void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
+
+void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
 {
    const float *x;
-   opus_val32 scale;
    int j;
+
    x = (const float *)_x;
    for (j=0;j<subframe;j++)
-      sub[j] = PCM2VAL(x[(j+offset)*C+c1]);
+      y[j] = PCM2VAL(x[(j+offset)*C+c1]);
    if (c2>-1)
    {
       for (j=0;j<subframe;j++)
-         sub[j] += PCM2VAL(x[(j+offset)*C+c2]);
+         y[j] += PCM2VAL(x[(j+offset)*C+c2]);
    } else if (c2==-2)
    {
       int c;
       for (c=1;c<C;c++)
       {
          for (j=0;j<subframe;j++)
-            sub[j] += PCM2VAL(x[(j+offset)*C+c]);
+            y[j] += PCM2VAL(x[(j+offset)*C+c]);
       }
    }
-#ifdef FIXED_POINT
-   scale = (1<<SIG_SHIFT);
-#else
-   scale = 1.f;
-#endif
-   if (C==-2)
-      scale /= C;
-   else
-      scale /= 2;
-   for (j=0;j<subframe;j++)
-      sub[j] *= scale;
 }
 #endif
 
-void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
+void downmix_int(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
 {
    const opus_int16 *x;
-   opus_val32 scale;
    int j;
+
    x = (const opus_int16 *)_x;
    for (j=0;j<subframe;j++)
-      sub[j] = x[(j+offset)*C+c1];
+      y[j] = x[(j+offset)*C+c1];
    if (c2>-1)
    {
       for (j=0;j<subframe;j++)
-         sub[j] += x[(j+offset)*C+c2];
+         y[j] += x[(j+offset)*C+c2];
    } else if (c2==-2)
    {
       int c;
       for (c=1;c<C;c++)
       {
          for (j=0;j<subframe;j++)
-            sub[j] += x[(j+offset)*C+c];
+            y[j] += x[(j+offset)*C+c];
       }
    }
-#ifdef FIXED_POINT
-   scale = (1<<SIG_SHIFT);
-#else
-   scale = 1.f/32768;
-#endif
-   if (C==-2)
-      scale /= C;
-   else
-      scale /= 2;
-   for (j=0;j<subframe;j++)
-      sub[j] *= scale;
 }
 
 opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)
@@ -811,53 +635,24 @@
       return -1;
    if (variable_duration == OPUS_FRAMESIZE_ARG)
       new_size = frame_size;
-   else if (variable_duration == OPUS_FRAMESIZE_VARIABLE)
-      new_size = Fs/50;
-   else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS)
-      new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS));
+   else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_120_MS)
+   {
+      if (variable_duration <= OPUS_FRAMESIZE_40_MS)
+         new_size = (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS);
+      else
+         new_size = (variable_duration-OPUS_FRAMESIZE_2_5_MS-2)*Fs/50;
+   }
    else
       return -1;
    if (new_size>frame_size)
       return -1;
-   if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&
-            50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs)
+   if (400*new_size!=Fs   && 200*new_size!=Fs   && 100*new_size!=Fs   &&
+        50*new_size!=Fs   &&  25*new_size!=Fs   &&  50*new_size!=3*Fs &&
+        50*new_size!=4*Fs &&  50*new_size!=5*Fs &&  50*new_size!=6*Fs)
       return -1;
    return new_size;
 }
 
-opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
-      int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
-      int delay_compensation, downmix_func downmix
-#ifndef DISABLE_FLOAT_API
-      , float *subframe_mem
-#endif
-      )
-{
-#ifndef DISABLE_FLOAT_API
-   if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200)
-   {
-      int LM = 3;
-      LM = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps,
-            0, subframe_mem, delay_compensation, downmix);
-      while ((Fs/400<<LM)>frame_size)
-         LM--;
-      frame_size = (Fs/400<<LM);
-   } else
-#else
-   (void)analysis_pcm;
-   (void)C;
-   (void)bitrate_bps;
-   (void)delay_compensation;
-   (void)downmix;
-#endif
-   {
-      frame_size = frame_size_select(frame_size, variable_duration, Fs);
-   }
-   if (frame_size<0)
-      return -1;
-   return frame_size;
-}
-
 opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
 {
    opus_val32 xx, xy, yy;
@@ -934,6 +729,348 @@
    return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower)));
 }
 
+static int decide_fec(int useInBandFEC, int PacketLoss_perc, int last_fec, int mode, int *bandwidth, opus_int32 rate)
+{
+   int orig_bandwidth;
+   if (!useInBandFEC || PacketLoss_perc == 0 || mode == MODE_CELT_ONLY)
+      return 0;
+   orig_bandwidth = *bandwidth;
+   for (;;)
+   {
+      opus_int32 hysteresis;
+      opus_int32 LBRR_rate_thres_bps;
+      /* Compute threshold for using FEC at the current bandwidth setting */
+      LBRR_rate_thres_bps = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND)];
+      hysteresis = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND) + 1];
+      if (last_fec == 1) LBRR_rate_thres_bps -= hysteresis;
+      if (last_fec == 0) LBRR_rate_thres_bps += hysteresis;
+      LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps,
+            125 - silk_min( PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
+      /* If loss <= 5%, we look at whether we have enough rate to enable FEC.
+         If loss > 5%, we decrease the bandwidth until we can enable FEC. */
+      if (rate > LBRR_rate_thres_bps)
+         return 1;
+      else if (PacketLoss_perc <= 5)
+         return 0;
+      else if (*bandwidth > OPUS_BANDWIDTH_NARROWBAND)
+         (*bandwidth)--;
+      else
+         break;
+   }
+   /* Couldn't find any bandwidth to enable FEC, keep original bandwidth. */
+   *bandwidth = orig_bandwidth;
+   return 0;
+}
+
+static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec) {
+   int entry;
+   int i;
+   int N;
+   int silk_rate;
+   static int rate_table[][5] = {
+  /*  |total| |-------- SILK------------|
+              |-- No FEC -| |--- FEC ---|
+               10ms   20ms   10ms   20ms */
+      {    0,     0,     0,     0,     0},
+      {12000, 10000, 10000, 11000, 11000},
+      {16000, 13500, 13500, 15000, 15000},
+      {20000, 16000, 16000, 18000, 18000},
+      {24000, 18000, 18000, 21000, 21000},
+      {32000, 22000, 22000, 28000, 28000},
+      {64000, 38000, 38000, 50000, 50000}
+   };
+   entry = 1 + frame20ms + 2*fec;
+   N = sizeof(rate_table)/sizeof(rate_table[0]);
+   for (i=1;i<N;i++)
+   {
+      if (rate_table[i][0] > rate) break;
+   }
+   if (i == N)
+   {
+      silk_rate = rate_table[i-1][entry];
+      /* For now, just give 50% of the extra bits to SILK. */
+      silk_rate += (rate-rate_table[i-1][0])/2;
+   } else {
+      opus_int32 lo, hi, x0, x1;
+      lo = rate_table[i-1][entry];
+      hi = rate_table[i][entry];
+      x0 = rate_table[i-1][0];
+      x1 = rate_table[i][0];
+      silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0);
+   }
+   if (!vbr)
+   {
+      /* Tiny boost to SILK for CBR. We should probably tune this better. */
+      silk_rate += 100;
+   }
+   if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND)
+      silk_rate += 300;
+   return silk_rate;
+}
+
+/* Returns the equivalent bitrate corresponding to 20 ms frames,
+   complexity 10 VBR operation. */
+static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels,
+      int frame_rate, int vbr, int mode, int complexity, int loss)
+{
+   opus_int32 equiv;
+   equiv = bitrate;
+   /* Take into account overhead from smaller frames. */
+   equiv -= (40*channels+20)*(frame_rate - 50);
+   /* CBR is about a 8% penalty for both SILK and CELT. */
+   if (!vbr)
+      equiv -= equiv/12;
+   /* Complexity makes about 10% difference (from 0 to 10) in general. */
+   equiv = equiv * (90+complexity)/100;
+   if (mode == MODE_SILK_ONLY || mode == MODE_HYBRID)
+   {
+      /* SILK complexity 0-1 uses the non-delayed-decision NSQ, which
+         costs about 20%. */
+      if (complexity<2)
+         equiv = equiv*4/5;
+      equiv -= equiv*loss/(6*loss + 10);
+   } else if (mode == MODE_CELT_ONLY) {
+      /* CELT complexity 0-4 doesn't have the pitch filter, which costs
+         about 10%. */
+      if (complexity<5)
+         equiv = equiv*9/10;
+   } else {
+      /* Mode not known yet */
+      /* Half the SILK loss*/
+      equiv -= equiv*loss/(12*loss + 20);
+   }
+   return equiv;
+}
+
+#ifndef DISABLE_FLOAT_API
+
+static int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth)
+{
+   int silence = 0;
+   opus_val32 sample_max = 0;
+#ifdef MLP_TRAINING
+   return 0;
+#endif
+   sample_max = celt_maxabs16(pcm, frame_size*channels);
+
+#ifdef FIXED_POINT
+   silence = (sample_max == 0);
+   (void)lsb_depth;
+#else
+   silence = (sample_max <= (opus_val16) 1 / (1 << lsb_depth));
+#endif
+
+   return silence;
+}
+
+#ifdef FIXED_POINT
+static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
+{
+   int i;
+   opus_val32 sample_max;
+   int max_shift;
+   int shift;
+   opus_val32 energy = 0;
+   int len = frame_size*channels;
+   (void)arch;
+   /* Max amplitude in the signal */
+   sample_max = celt_maxabs16(pcm, len);
+
+   /* Compute the right shift required in the MAC to avoid an overflow */
+   max_shift = celt_ilog2(len);
+   shift = IMAX(0, (celt_ilog2(sample_max) << 1) + max_shift - 28);
+
+   /* Compute the energy */
+   for (i=0; i<len; i++)
+      energy += SHR32(MULT16_16(pcm[i], pcm[i]), shift);
+
+   /* Normalize energy by the frame size and left-shift back to the original position */
+   energy /= len;
+   energy = SHL32(energy, shift);
+
+   return energy;
+}
+#else
+static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
+{
+   int len = frame_size*channels;
+   return celt_inner_prod(pcm, pcm, len, arch)/len;
+}
+#endif
+
+/* Decides if DTX should be turned on (=1) or off (=0) */
+static int decide_dtx_mode(float activity_probability,    /* probability that current frame contains speech/music */
+                           int *nb_no_activity_frames,    /* number of consecutive frames with no activity */
+                           opus_val32 peak_signal_energy, /* peak energy of desired signal detected so far */
+                           const opus_val16 *pcm,         /* input pcm signal */
+                           int frame_size,                /* frame size */
+                           int channels,
+                           int is_silence,                 /* only digital silence detected in this frame */
+                           int arch
+                          )
+{
+   int is_noise;
+   opus_val32 noise_energy;
+   int is_sufficiently_quiet;
+
+   if (!is_silence)
+   {
+      is_noise = activity_probability < DTX_ACTIVITY_THRESHOLD;
+      if (is_noise)
+      {
+         noise_energy = compute_frame_energy(pcm, frame_size, channels, arch);
+         is_sufficiently_quiet = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy);
+      }
+   }
+
+   if (is_silence || (is_noise && is_sufficiently_quiet))
+   {
+      /* The number of consecutive DTX frames should be within the allowed bounds */
+      (*nb_no_activity_frames)++;
+
+      if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX)
+      {
+         if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX))
+            /* Valid frame for DTX! */
+            return 1;
+         else
+            (*nb_no_activity_frames) = NB_SPEECH_FRAMES_BEFORE_DTX;
+      }
+   } else
+      (*nb_no_activity_frames) = 0;
+
+   return 0;
+}
+
+#endif
+
+static opus_int32 encode_multiframe_packet(OpusEncoder *st,
+                                           const opus_val16 *pcm,
+                                           int nb_frames,
+                                           int frame_size,
+                                           unsigned char *data,
+                                           opus_int32 out_data_bytes,
+                                           int to_celt,
+                                           int lsb_depth,
+                                           int float_api)
+{
+   int i;
+   int ret = 0;
+   VARDECL(unsigned char, tmp_data);
+   int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
+   VARDECL(OpusRepacketizer, rp);
+   int max_header_bytes;
+   opus_int32 bytes_per_frame;
+   opus_int32 cbr_bytes;
+   opus_int32 repacketize_len;
+   int tmp_len;
+   ALLOC_STACK;
+
+   /* Worst cases:
+    * 2 frames: Code 2 with different compressed sizes
+    * >2 frames: Code 3 VBR */
+   max_header_bytes = nb_frames == 2 ? 3 : (2+(nb_frames-1)*2);
+
+   if (st->use_vbr || st->user_bitrate_bps==OPUS_BITRATE_MAX)
+      repacketize_len = out_data_bytes;
+   else {
+      cbr_bytes = 3*st->bitrate_bps/(3*8*st->Fs/(frame_size*nb_frames));
+      repacketize_len = IMIN(cbr_bytes, out_data_bytes);
+   }
+   bytes_per_frame = IMIN(1276, 1+(repacketize_len-max_header_bytes)/nb_frames);
+
+   ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
+   ALLOC(rp, 1, OpusRepacketizer);
+   opus_repacketizer_init(rp);
+
+   bak_mode = st->user_forced_mode;
+   bak_bandwidth = st->user_bandwidth;
+   bak_channels = st->force_channels;
+
+   st->user_forced_mode = st->mode;
+   st->user_bandwidth = st->bandwidth;
+   st->force_channels = st->stream_channels;
+
+   bak_to_mono = st->silk_mode.toMono;
+   if (bak_to_mono)
+      st->force_channels = 1;
+   else
+      st->prev_channels = st->stream_channels;
+
+   for (i=0;i<nb_frames;i++)
+   {
+      st->silk_mode.toMono = 0;
+      st->nonfinal_frame = i<(nb_frames-1);
+
+      /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
+      if (to_celt && i==nb_frames-1)
+         st->user_forced_mode = MODE_CELT_ONLY;
+
+      tmp_len = opus_encode_native(st, pcm+i*(st->channels*frame_size), frame_size,
+         tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth, NULL, 0, 0, 0, 0,
+         NULL, float_api);
+
+      if (tmp_len<0)
+      {
+         RESTORE_STACK;
+         return OPUS_INTERNAL_ERROR;
+      }
+
+      ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
+
+      if (ret<0)
+      {
+         RESTORE_STACK;
+         return OPUS_INTERNAL_ERROR;
+      }
+   }
+
+   ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
+
+   if (ret<0)
+   {
+      RESTORE_STACK;
+      return OPUS_INTERNAL_ERROR;
+   }
+
+   /* Discard configs that were forced locally for the purpose of repacketization */
+   st->user_forced_mode = bak_mode;
+   st->user_bandwidth = bak_bandwidth;
+   st->force_channels = bak_channels;
+   st->silk_mode.toMono = bak_to_mono;
+
+   RESTORE_STACK;
+   return ret;
+}
+
+static int compute_redundancy_bytes(opus_int32 max_data_bytes, opus_int32 bitrate_bps, int frame_rate, int channels)
+{
+   int redundancy_bytes_cap;
+   int redundancy_bytes;
+   opus_int32 redundancy_rate;
+   int base_bits;
+   opus_int32 available_bits;
+   base_bits = (40*channels+20);
+
+   /* Equivalent rate for 5 ms frames. */
+   redundancy_rate = bitrate_bps + base_bits*(200 - frame_rate);
+   /* For VBR, further increase the bitrate if we can afford it. It's pretty short
+      and we'll avoid artefacts. */
+   redundancy_rate = 3*redundancy_rate/2;
+   redundancy_bytes = redundancy_rate/1600;
+
+   /* Compute the max rate we can use given CBR or VBR with cap. */
+   available_bits = max_data_bytes*8 - 2*base_bits;
+   redundancy_bytes_cap = (available_bits*240/(240+48000/frame_rate) + base_bits)/8;
+   redundancy_bytes = IMIN(redundancy_bytes, redundancy_bytes_cap);
+   /* It we can't get enough bits for redundancy to be worth it, rely on the decoder PLC. */
+   if (redundancy_bytes > 4 + 8*channels)
+      redundancy_bytes = IMIN(257, redundancy_bytes);
+   else
+      redundancy_bytes = 0;
+   return redundancy_bytes;
+}
+
 opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
                 unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
                 const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
@@ -971,6 +1108,7 @@
     AnalysisInfo analysis_info;
     int analysis_read_pos_bak=-1;
     int analysis_read_subframe_bak=-1;
+    int is_silence = 0;
 #endif
     VARDECL(opus_val16, tmp_prefill);
 
@@ -979,15 +1117,19 @@
     max_data_bytes = IMIN(1276, out_data_bytes);
 
     st->rangeFinal = 0;
-    if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
-         50*frame_size != st->Fs &&  25*frame_size != st->Fs &&  50*frame_size != 3*st->Fs)
-         || (400*frame_size < st->Fs)
-         || max_data_bytes<=0
-         )
+    if (frame_size <= 0 || max_data_bytes <= 0)
     {
        RESTORE_STACK;
        return OPUS_BAD_ARG;
     }
+
+    /* Cannot encode 100 ms in 1 byte */
+    if (max_data_bytes==1 && st->Fs==(frame_size*10))
+    {
+      RESTORE_STACK;
+      return OPUS_BUFFER_TOO_SMALL;
+    }
+
     silk_enc = (char*)st+st->silk_enc_offset;
     celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
     if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
@@ -1001,25 +1143,42 @@
 #ifndef DISABLE_FLOAT_API
     analysis_info.valid = 0;
 #ifdef FIXED_POINT
-    if (st->silk_mode.complexity >= 10 && st->Fs==48000)
+    if (st->silk_mode.complexity >= 10 && st->Fs>=16000)
 #else
-    if (st->silk_mode.complexity >= 7 && st->Fs==48000)
+    if (st->silk_mode.complexity >= 7 && st->Fs>=16000)
 #endif
     {
-       analysis_read_pos_bak = st->analysis.read_pos;
-       analysis_read_subframe_bak = st->analysis.read_subframe;
-       run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
-             c1, c2, analysis_channels, st->Fs,
-             lsb_depth, downmix, &analysis_info);
+       if (is_digital_silence(pcm, frame_size, st->channels, lsb_depth))
+       {
+          is_silence = 1;
+       } else {
+          analysis_read_pos_bak = st->analysis.read_pos;
+          analysis_read_subframe_bak = st->analysis.read_subframe;
+          run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
+                c1, c2, analysis_channels, st->Fs,
+                lsb_depth, downmix, &analysis_info);
+       }
+
+       /* Track the peak signal energy */
+       if (!is_silence && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD)
+          st->peak_signal_energy = MAX32(MULT16_32_Q15(QCONST16(0.999f, 15), st->peak_signal_energy),
+                compute_frame_energy(pcm, frame_size, st->channels, st->arch));
     }
 #else
     (void)analysis_pcm;
     (void)analysis_size;
+    (void)c1;
+    (void)c2;
+    (void)analysis_channels;
+    (void)downmix;
 #endif
 
-    st->voice_ratio = -1;
-
 #ifndef DISABLE_FLOAT_API
+    /* Reset voice_ratio if this frame is not silent or if analysis is disabled.
+     * Otherwise, preserve voice_ratio from the last non-silent frame */
+    if (!is_silence)
+      st->voice_ratio = -1;
+
     st->detected_bandwidth = 0;
     if (analysis_info.valid)
     {
@@ -1039,6 +1198,8 @@
        else
           st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
     }
+#else
+    st->voice_ratio = -1;
 #endif
 
     if (st->channels==2 && st->force_channels!=1)
@@ -1052,12 +1213,13 @@
     if (!st->use_vbr)
     {
        int cbrBytes;
-       /* Multiply by 3 to make sure the division is exact. */
-       int frame_rate3 = 3*st->Fs/frame_size;
+       /* Multiply by 12 to make sure the division is exact. */
+       int frame_rate12 = 12*st->Fs/frame_size;
        /* We need to make sure that "int" values always fit in 16 bits. */
-       cbrBytes = IMIN( (3*st->bitrate_bps/8 + frame_rate3/2)/frame_rate3, max_data_bytes);
-       st->bitrate_bps = cbrBytes*(opus_int32)frame_rate3*8/3;
-       max_data_bytes = cbrBytes;
+       cbrBytes = IMIN( (12*st->bitrate_bps/8 + frame_rate12/2)/frame_rate12, max_data_bytes);
+       st->bitrate_bps = cbrBytes*(opus_int32)frame_rate12*8/12;
+       /* Make sure we provide at least one byte to avoid failing. */
+       max_data_bytes = IMAX(1, cbrBytes);
     }
     if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
        || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
@@ -1065,25 +1227,63 @@
        /*If the space is too low to do something useful, emit 'PLC' frames.*/
        int tocmode = st->mode;
        int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;
+       int packet_code = 0;
+       int num_multiframes = 0;
+
        if (tocmode==0)
           tocmode = MODE_SILK_ONLY;
        if (frame_rate>100)
           tocmode = MODE_CELT_ONLY;
-       if (frame_rate < 50)
-          tocmode = MODE_SILK_ONLY;
+       /* 40 ms -> 2 x 20 ms if in CELT_ONLY or HYBRID mode */
+       if (frame_rate==25 && tocmode!=MODE_SILK_ONLY)
+       {
+          frame_rate = 50;
+          packet_code = 1;
+       }
+
+       /* >= 60 ms frames */
+       if (frame_rate<=16)
+       {
+          /* 1 x 60 ms, 2 x 40 ms, 2 x 60 ms */
+          if (out_data_bytes==1 || (tocmode==MODE_SILK_ONLY && frame_rate!=10))
+          {
+             tocmode = MODE_SILK_ONLY;
+
+             packet_code = frame_rate <= 12;
+             frame_rate = frame_rate == 12 ? 25 : 16;
+          }
+          else
+          {
+             num_multiframes = 50/frame_rate;
+             frame_rate = 50;
+             packet_code = 3;
+          }
+       }
+
        if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)
           bw=OPUS_BANDWIDTH_WIDEBAND;
        else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
           bw=OPUS_BANDWIDTH_NARROWBAND;
        else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
           bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
+
        data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
-       ret = 1;
+       data[0] |= packet_code;
+
+       ret = packet_code <= 1 ? 1 : 2;
+
+       max_data_bytes = IMAX(max_data_bytes, ret);
+
+       if (packet_code==3)
+          data[1] = num_multiframes;
+
        if (!st->use_vbr)
        {
           ret = opus_packet_pad(data, ret, max_data_bytes);
           if (ret == OPUS_OK)
              ret = max_data_bytes;
+          else
+             ret = OPUS_INTERNAL_ERROR;
        }
        RESTORE_STACK;
        return ret;
@@ -1091,7 +1291,8 @@
     max_rate = frame_rate*max_data_bytes*8;
 
     /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
-    equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50);
+    equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size,
+          st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
 
     if (st->signal_type == OPUS_SIGNAL_VOICE)
        voice_est = 127;
@@ -1132,7 +1333,9 @@
        }
 #endif
     }
-    equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50);
+    /* Update equivalent rate for channels decision. */
+    equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
+          st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
 
     /* Mode selection depending on application and signal type */
     if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
@@ -1181,10 +1384,21 @@
        /* When FEC is enabled and there's enough packet loss, use SILK */
        if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
           st->mode = MODE_SILK_ONLY;
-       /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */
+       /* When encoding voice and DTX is enabled but the generalized DTX cannot be used,
+          because of complexity and sampling frequency settings, switch to SILK DTX and
+          set the encoder to SILK mode */
+#ifndef DISABLE_FLOAT_API
+       st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence);
+#else
+       st->silk_mode.useDTX = st->use_dtx;
+#endif
        if (st->silk_mode.useDTX && voice_est > 100)
           st->mode = MODE_SILK_ONLY;
 #endif
+
+       /* If max_data_bytes represents less than 6 kb/s, switch to CELT-only mode */
+       if (max_data_bytes < (frame_rate > 50 ? 9000 : 6000)*frame_size / (st->Fs * 8))
+          st->mode = MODE_CELT_ONLY;
     } else {
        st->mode = st->user_forced_mode;
     }
@@ -1194,19 +1408,6 @@
        st->mode = MODE_CELT_ONLY;
     if (st->lfe)
        st->mode = MODE_CELT_ONLY;
-    /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */
-    if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8))
-       st->mode = MODE_CELT_ONLY;
-
-    if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
-          && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
-    {
-       /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
-       st->silk_mode.toMono = 1;
-       st->stream_channels = 2;
-    } else {
-       st->silk_mode.toMono = 0;
-    }
 
     if (st->prev_mode > 0 &&
         ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
@@ -1226,23 +1427,22 @@
             }
         }
     }
-    /* For the first frame at a new SILK bandwidth */
-    if (st->silk_bw_switch)
+
+    /* When encoding multiframes, we can ask for a switch to CELT only in the last frame. This switch
+     * is processed above as the requested mode shouldn't interrupt stereo->mono transition. */
+    if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
+          && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
     {
-       redundancy = 1;
-       celt_to_silk = 1;
-       st->silk_bw_switch = 0;
-       prefill=1;
+       /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
+       st->silk_mode.toMono = 1;
+       st->stream_channels = 2;
+    } else {
+       st->silk_mode.toMono = 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);
-    }
+    /* Update equivalent rate with mode decision. */
+    equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
+          st->use_vbr, st->mode, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
 
     if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
     {
@@ -1257,17 +1457,7 @@
         const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
         opus_int32 bandwidth_thresholds[8];
         int bandwidth = OPUS_BANDWIDTH_FULLBAND;
-        opus_int32 equiv_rate2;
 
-        equiv_rate2 = equiv_rate;
-        if (st->mode != MODE_CELT_ONLY)
-        {
-           /* Adjust the threshold +/- 10% depending on complexity */
-           equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;
-           /* CBR is less efficient by ~1 kb/s */
-           if (!st->use_vbr)
-              equiv_rate2 -= 1000;
-        }
         if (st->channels==2 && st->force_channels!=1)
         {
            voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
@@ -1288,15 +1478,15 @@
             hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];
             if (!st->first)
             {
-                if (st->bandwidth >= bandwidth)
+                if (st->auto_bandwidth >= bandwidth)
                     threshold -= hysteresis;
                 else
                     threshold += hysteresis;
             }
-            if (equiv_rate2 >= threshold)
+            if (equiv_rate >= threshold)
                 break;
         } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
-        st->bandwidth = bandwidth;
+        st->bandwidth = st->auto_bandwidth = bandwidth;
         /* Prevents any transition to SWB/FB until the SILK layer has fully
            switched to WB mode and turned the variable LP filter off */
         if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
@@ -1349,6 +1539,8 @@
        st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
     }
 #endif
+    st->silk_mode.LBRR_coded = decide_fec(st->silk_mode.useInBandFEC, st->silk_mode.packetLossPercentage,
+          st->silk_mode.LBRR_coded, st->mode, &st->bandwidth, equiv_rate);
     celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));
 
     /* CELT mode doesn't support mediumband, use wideband instead */
@@ -1357,15 +1549,34 @@
     if (st->lfe)
        st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
 
-    /* Can't support higher than wideband for >20 ms frames */
-    if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND))
+    curr_bandwidth = st->bandwidth;
+
+    /* Chooses the appropriate mode for speech
+       *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
+    if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
+        st->mode = MODE_HYBRID;
+    if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
+        st->mode = MODE_SILK_ONLY;
+
+    /* Can't support higher than >60 ms frames, and >20 ms when in Hybrid or CELT-only modes */
+    if ((frame_size > st->Fs/50 && (st->mode != MODE_SILK_ONLY)) || frame_size > 3*st->Fs/50)
     {
-       VARDECL(unsigned char, tmp_data);
+       int enc_frame_size;
        int nb_frames;
-       int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
-       VARDECL(OpusRepacketizer, rp);
-       opus_int32 bytes_per_frame;
-       opus_int32 repacketize_len;
+
+       if (st->mode == MODE_SILK_ONLY)
+       {
+         if (frame_size == 2*st->Fs/25)  /* 80 ms -> 2x 40 ms */
+           enc_frame_size = st->Fs/25;
+         else if (frame_size == 3*st->Fs/25)  /* 120 ms -> 2x 60 ms */
+           enc_frame_size = 3*st->Fs/50;
+         else                            /* 100 ms -> 5x 20 ms */
+           enc_frame_size = st->Fs/50;
+       }
+       else
+         enc_frame_size = st->Fs/50;
+
+       nb_frames = frame_size/enc_frame_size;
 
 #ifndef DISABLE_FLOAT_API
        if (analysis_read_pos_bak!= -1)
@@ -1375,74 +1586,33 @@
        }
 #endif
 
-       nb_frames = frame_size > st->Fs/25 ? 3 : 2;
-       bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
+       ret = encode_multiframe_packet(st, pcm, nb_frames, enc_frame_size, data,
+                                      out_data_bytes, to_celt, lsb_depth, float_api);
 
-       ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
-
-       ALLOC(rp, 1, OpusRepacketizer);
-       opus_repacketizer_init(rp);
-
-       bak_mode = st->user_forced_mode;
-       bak_bandwidth = st->user_bandwidth;
-       bak_channels = st->force_channels;
-
-       st->user_forced_mode = st->mode;
-       st->user_bandwidth = st->bandwidth;
-       st->force_channels = st->stream_channels;
-       bak_to_mono = st->silk_mode.toMono;
-
-       if (bak_to_mono)
-          st->force_channels = 1;
-       else
-          st->prev_channels = st->stream_channels;
-       for (i=0;i<nb_frames;i++)
-       {
-          int tmp_len;
-          st->silk_mode.toMono = 0;
-          /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
-          if (to_celt && i==nb_frames-1)
-             st->user_forced_mode = MODE_CELT_ONLY;
-          tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50,
-                tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth,
-                NULL, 0, c1, c2, analysis_channels, downmix, float_api);
-          if (tmp_len<0)
-          {
-             RESTORE_STACK;
-             return OPUS_INTERNAL_ERROR;
-          }
-          ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
-          if (ret<0)
-          {
-             RESTORE_STACK;
-             return OPUS_INTERNAL_ERROR;
-          }
-       }
-       if (st->use_vbr)
-          repacketize_len = out_data_bytes;
-       else
-          repacketize_len = IMIN(3*st->bitrate_bps/(3*8*50/nb_frames), out_data_bytes);
-       ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
-       if (ret<0)
-       {
-          RESTORE_STACK;
-          return OPUS_INTERNAL_ERROR;
-       }
-       st->user_forced_mode = bak_mode;
-       st->user_bandwidth = bak_bandwidth;
-       st->force_channels = bak_channels;
-       st->silk_mode.toMono = bak_to_mono;
        RESTORE_STACK;
        return ret;
     }
-    curr_bandwidth = st->bandwidth;
 
-    /* Chooses the appropriate mode for speech
-       *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
-    if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
-        st->mode = MODE_HYBRID;
-    if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
-        st->mode = MODE_SILK_ONLY;
+    /* For the first frame at a new SILK bandwidth */
+    if (st->silk_bw_switch)
+    {
+       redundancy = 1;
+       celt_to_silk = 1;
+       st->silk_bw_switch = 0;
+       prefill=1;
+    }
+
+    /* If we decided to go with CELT, make sure redundancy is off, no matter what
+       we decided earlier. */
+    if (st->mode == MODE_CELT_ONLY)
+        redundancy = 0;
+
+    if (redundancy)
+    {
+       redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels);
+       if (redundancy_bytes == 0)
+          redundancy = 0;
+    }
 
     /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
     bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
@@ -1467,7 +1637,7 @@
 
     if (st->application == OPUS_APPLICATION_VOIP)
     {
-       hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
+       hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs, st->arch);
     } else {
        dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
     }
@@ -1502,27 +1672,14 @@
         /* Distribute bits between SILK and CELT */
         total_bitRate = 8 * bytes_target * frame_rate;
         if( st->mode == MODE_HYBRID ) {
-            int HB_gain_ref;
             /* Base rate for SILK */
-            st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );
-            if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
-                /* SILK gets 2/3 of the remaining bits */
-                st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3;
-            } else { /* FULLBAND */
-                /* SILK gets 3/5 of the remaining bits */
-                st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5;
-            }
-            /* Don't let SILK use more than 80% */
-            if( st->silk_mode.bitRate > total_bitRate * 4/5 ) {
-                st->silk_mode.bitRate = total_bitRate * 4/5;
-            }
+            st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
+                  curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded);
             if (!st->energy_masking)
             {
                /* Increasingly attenuate high band when it gets allocated fewer bits */
                celt_rate = total_bitRate - st->silk_mode.bitRate;
-               HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
-               HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
-               HB_gain = HB_gain < (opus_val32)Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
+               HB_gain = Q15ONE - SHR32(celt_exp2(-celt_rate * QCONST16(1.f/1024, 10)), 1);
             }
         } else {
             /* SILK gets all bits */
@@ -1569,7 +1726,6 @@
               st->silk_mode.bitRate += 3*rate_offset/5;
            else
               st->silk_mode.bitRate += rate_offset;
-           bytes_target += rate_offset * frame_size / (8 * st->Fs);
         }
 
         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
@@ -1590,40 +1746,52 @@
             st->silk_mode.minInternalSampleRate = 8000;
         }
 
+        st->silk_mode.maxInternalSampleRate = 16000;
         if (st->mode == MODE_SILK_ONLY)
         {
            opus_int32 effective_max_rate = max_rate;
-           st->silk_mode.maxInternalSampleRate = 16000;
            if (frame_rate > 50)
               effective_max_rate = effective_max_rate*2/3;
-           if (effective_max_rate < 13000)
+           if (effective_max_rate < 8000)
            {
               st->silk_mode.maxInternalSampleRate = 12000;
               st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);
            }
-           if (effective_max_rate < 9600)
+           if (effective_max_rate < 7000)
            {
               st->silk_mode.maxInternalSampleRate = 8000;
               st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);
            }
-        } else {
-           st->silk_mode.maxInternalSampleRate = 16000;
         }
 
         st->silk_mode.useCBR = !st->use_vbr;
 
         /* Call SILK encoder for the low band */
-        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*/
-        if (st->mode == MODE_HYBRID)
-           st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10;
+        /* Max bits for SILK, counting ToC, redundancy bytes, and optionally redundancy. */
+        st->silk_mode.maxBits = (max_data_bytes-1)*8;
+        if (redundancy && redundancy_bytes >= 2)
+        {
+           /* Counting 1 bit for redundancy position and 20 bits for flag+size (only for hybrid). */
+           st->silk_mode.maxBits -= redundancy_bytes*8 + 1;
+           if (st->mode == MODE_HYBRID)
+              st->silk_mode.maxBits -= 20;
+        }
         if (st->silk_mode.useCBR)
         {
-           st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8;
-           /* 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 (st->mode == MODE_HYBRID)
+           {
+              st->silk_mode.maxBits = IMIN(st->silk_mode.maxBits, st->silk_mode.bitRate * frame_size / st->Fs);
+           }
+        } else {
+           /* Constrained VBR. */
+           if (st->mode == MODE_HYBRID)
+           {
+              /* Compute SILK bitrate corresponding to the max total bits available */
+              opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size,
+                    curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded);
+              st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
+           }
         }
 
         if (prefill)
@@ -1662,13 +1830,7 @@
            RESTORE_STACK;
            return OPUS_INTERNAL_ERROR;
         }
-        if (nBytes==0)
-        {
-           st->rangeFinal = 0;
-           data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
-           RESTORE_STACK;
-           return 1;
-        }
+
         /* Extract SILK internal bandwidth for signaling in first byte */
         if( st->mode == MODE_SILK_ONLY ) {
             if( st->silk_mode.internalSampleRate == 8000 ) {
@@ -1682,11 +1844,21 @@
             silk_assert( st->silk_mode.internalSampleRate == 16000 );
         }
 
-        st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
+        st->silk_mode.opusCanSwitch = st->silk_mode.switchReady && !st->nonfinal_frame;
+
+        if (nBytes==0)
+        {
+           st->rangeFinal = 0;
+           data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
+           RESTORE_STACK;
+           return 1;
+        }
+
         /* FIXME: How do we allocate the redundancy for CBR? */
         if (st->silk_mode.opusCanSwitch)
         {
-           redundancy = 1;
+           redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels);
+           redundancy = (redundancy_bytes != 0);
            celt_to_silk = 0;
            st->silk_bw_switch = 1;
         }
@@ -1727,40 +1899,18 @@
 
         if (st->mode == MODE_HYBRID)
         {
-            int len;
-
-            len = (ec_tell(&enc)+7)>>3;
-            if (redundancy)
-               len += st->mode == MODE_HYBRID ? 3 : 1;
             if( st->use_vbr ) {
-                nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
-            } else {
-                /* check if SILK used up too much */
-                nb_compr_bytes = len > bytes_target ? len : bytes_target;
+                celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
+                celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(0));
             }
         } else {
             if (st->use_vbr)
             {
-                opus_int32 bonus=0;
-#ifndef DISABLE_FLOAT_API
-                if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)
-                {
-                   bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);
-                   if (analysis_info.valid)
-                      bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info.tonality));
-                }
-#endif
                 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+bonus));
-                nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
-            } else {
-                nb_compr_bytes = bytes_target;
+                celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
             }
         }
-
-    } else {
-        nb_compr_bytes = 0;
     }
 
     ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
@@ -1786,7 +1936,7 @@
     }
     st->prev_HB_gain = HB_gain;
     if (st->mode != MODE_HYBRID || st->stream_channels==1)
-       st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),2*IMAX(0,equiv_rate-30000));
+       st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),2*IMAX(0,equiv_rate-24000));
     if( !st->energy_masking && st->channels == 2 ) {
         /* Apply stereo width reduction (at low bitrates) */
         if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
@@ -1809,19 +1959,23 @@
     if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1))
     {
         /* For SILK mode, the redundancy is inferred from the length */
-        if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes))
+        if (st->mode == MODE_HYBRID)
            ec_enc_bit_logp(&enc, redundancy, 12);
         if (redundancy)
         {
             int max_redundancy;
             ec_enc_bit_logp(&enc, celt_to_silk, 1);
             if (st->mode == MODE_HYBRID)
-               max_redundancy = (max_data_bytes-1)-nb_compr_bytes;
+            {
+               /* Reserve the 8 bits needed for the redundancy length,
+                  and at least a few bits for CELT if possible */
+               max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+8+3+7)>>3);
+            }
             else
                max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
             /* Target the same bit-rate for redundancy as for the rest,
                up to a max of 257 bytes */
-            redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);
+            redundancy_bytes = IMIN(max_redundancy, redundancy_bytes);
             redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));
             if (st->mode == MODE_HYBRID)
                 ec_enc_uint(&enc, redundancy_bytes-2, 256);
@@ -1843,7 +1997,7 @@
         ec_enc_done(&enc);
         nb_compr_bytes = ret;
     } else {
-       nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
+       nb_compr_bytes = (max_data_bytes-1)-redundancy_bytes;
        ec_enc_shrink(&enc, nb_compr_bytes);
     }
 
@@ -1851,6 +2005,14 @@
     if (redundancy || st->mode != MODE_SILK_ONLY)
        celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
 #endif
+    if (st->mode == MODE_HYBRID) {
+       SILKInfo info;
+       info.signalType = st->silk_mode.signalType;
+       info.offset = st->silk_mode.offset;
+       celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO(&info));
+    } else {
+       celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO((SILKInfo*)NULL));
+    }
 
     /* 5 ms redundant frame for CELT->SILK */
     if (redundancy && celt_to_silk)
@@ -1858,6 +2020,7 @@
         int err;
         celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
         celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
+        celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
         err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
         if (err < 0)
         {
@@ -1881,15 +2044,25 @@
            celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
            celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
         }
-        /* If false, we already busted the budget and we'll end up with a "PLC packet" */
+        /* If false, we already busted the budget and we'll end up with a "PLC frame" */
         if (ec_tell(&enc) <= 8*nb_compr_bytes)
         {
+           /* Set the bitrate again if it was overridden in the redundancy code above*/
+           if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
+              celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
+           celt_encoder_ctl(celt_enc, OPUS_SET_VBR(st->use_vbr));
            ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
            if (ret < 0)
            {
               RESTORE_STACK;
               return OPUS_INTERNAL_ERROR;
            }
+           /* Put CELT->SILK redundancy data in the right place. */
+           if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
+           {
+              OPUS_MOVE(data+ret, data+nb_compr_bytes, redundancy_bytes);
+              nb_compr_bytes = nb_compr_bytes+redundancy_bytes;
+           }
         }
     }
 
@@ -1905,7 +2078,15 @@
         celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
         celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
         celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
+        celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
+        celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
 
+        if (st->mode == MODE_HYBRID)
+        {
+           /* Shrink packet to what the encoder actually used. */
+           nb_compr_bytes = ret;
+           ec_enc_shrink(&enc, nb_compr_bytes);
+        }
         /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
         celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);
 
@@ -1935,6 +2116,21 @@
 
     st->first = 0;
 
+    /* DTX decision */
+#ifndef DISABLE_FLOAT_API
+    if (st->use_dtx && (analysis_info.valid || is_silence))
+    {
+       if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames,
+             st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch))
+       {
+          st->rangeFinal = 0;
+          data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
+          RESTORE_STACK;
+          return 1;
+       }
+    }
+#endif
+
     /* In the unlikely case that the SILK encoder busted its target, tell
        the decoder to call the PLC */
     if (ec_tell(&enc) > (max_data_bytes-1)*8)
@@ -1962,7 +2158,6 @@
     if (!st->use_vbr)
     {
        if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)
-
        {
           RESTORE_STACK;
           return OPUS_INTERNAL_ERROR;
@@ -1981,18 +2176,15 @@
 {
    int i, ret;
    int frame_size;
-   int delay_compensation;
    VARDECL(opus_int16, in);
    ALLOC_STACK;
 
-   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
-      delay_compensation = 0;
-   else
-      delay_compensation = st->delay_compensation;
-   frame_size = compute_frame_size(pcm, analysis_frame_size,
-         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
-         delay_compensation, downmix_float, st->analysis.subframe_mem);
-
+   frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
+   if (frame_size <= 0)
+   {
+      RESTORE_STACK;
+      return OPUS_BAD_ARG;
+   }
    ALLOC(in, frame_size*st->channels, opus_int16);
 
    for (i=0;i<frame_size*st->channels;i++)
@@ -2008,18 +2200,7 @@
                 unsigned char *data, opus_int32 out_data_bytes)
 {
    int frame_size;
-   int delay_compensation;
-   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
-      delay_compensation = 0;
-   else
-      delay_compensation = st->delay_compensation;
-   frame_size = compute_frame_size(pcm, analysis_frame_size,
-         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
-         delay_compensation, downmix_int
-#ifndef DISABLE_FLOAT_API
-         , st->analysis.subframe_mem
-#endif
-         );
+   frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
    return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16,
                              pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);
 }
@@ -2030,18 +2211,15 @@
 {
    int i, ret;
    int frame_size;
-   int delay_compensation;
    VARDECL(float, in);
    ALLOC_STACK;
 
-   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
-      delay_compensation = 0;
-   else
-      delay_compensation = st->delay_compensation;
-   frame_size = compute_frame_size(pcm, analysis_frame_size,
-         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
-         delay_compensation, downmix_int, st->analysis.subframe_mem);
-
+   frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
+   if (frame_size <= 0)
+   {
+      RESTORE_STACK;
+      return OPUS_BAD_ARG;
+   }
    ALLOC(in, frame_size*st->channels, float);
 
    for (i=0;i<frame_size*st->channels;i++)
@@ -2055,14 +2233,7 @@
                       unsigned char *data, opus_int32 out_data_bytes)
 {
    int frame_size;
-   int delay_compensation;
-   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
-      delay_compensation = 0;
-   else
-      delay_compensation = st->delay_compensation;
-   frame_size = compute_frame_size(pcm, analysis_frame_size,
-         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
-         delay_compensation, downmix_float, st->analysis.subframe_mem);
+   frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
    return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,
                              pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
 }
@@ -2093,6 +2264,9 @@
                break;
             }
             st->application = value;
+#ifndef DISABLE_FLOAT_API
+            st->analysis.application = value;
+#endif
         }
         break;
         case OPUS_GET_APPLICATION_REQUEST:
@@ -2211,7 +2385,7 @@
             {
                goto bad_arg;
             }
-            st->silk_mode.useDTX = value;
+            st->use_dtx = value;
         }
         break;
         case OPUS_GET_DTX_REQUEST:
@@ -2221,7 +2395,7 @@
             {
                goto bad_arg;
             }
-            *value = st->silk_mode.useDTX;
+            *value = st->use_dtx;
         }
         break;
         case OPUS_SET_COMPLEXITY_REQUEST:
@@ -2422,10 +2596,11 @@
         case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
         {
             opus_int32 value = va_arg(ap, opus_int32);
-            if (value != OPUS_FRAMESIZE_ARG   && value != OPUS_FRAMESIZE_2_5_MS &&
-                value != OPUS_FRAMESIZE_5_MS  && value != OPUS_FRAMESIZE_10_MS  &&
-                value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS  &&
-                value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE)
+            if (value != OPUS_FRAMESIZE_ARG    && value != OPUS_FRAMESIZE_2_5_MS &&
+                value != OPUS_FRAMESIZE_5_MS   && value != OPUS_FRAMESIZE_10_MS  &&
+                value != OPUS_FRAMESIZE_20_MS  && value != OPUS_FRAMESIZE_40_MS  &&
+                value != OPUS_FRAMESIZE_60_MS  && value != OPUS_FRAMESIZE_80_MS  &&
+                value != OPUS_FRAMESIZE_100_MS && value != OPUS_FRAMESIZE_120_MS)
             {
                goto bad_arg;
             }
@@ -2459,6 +2634,26 @@
            *value = st->silk_mode.reducedDependency;
         }
         break;
+        case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
+        {
+            opus_int32 value = va_arg(ap, opus_int32);
+            if(value<0 || value>1)
+            {
+               goto bad_arg;
+            }
+            celt_encoder_ctl(celt_enc, OPUS_SET_PHASE_INVERSION_DISABLED(value));
+        }
+        break;
+        case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
+        {
+            opus_int32 *value = va_arg(ap, opus_int32*);
+            if (!value)
+            {
+               goto bad_arg;
+            }
+            celt_encoder_ctl(celt_enc, OPUS_GET_PHASE_INVERSION_DISABLED(value));
+        }
+        break;
         case OPUS_RESET_STATE:
         {
            void *silk_enc;
diff --git a/src/opus_multistream_decoder.c b/src/opus_multistream_decoder.c
index b95eaa6..e421726 100644
--- a/src/opus_multistream_decoder.c
+++ b/src/opus_multistream_decoder.c
@@ -237,7 +237,8 @@
    for (s=0;s<st->layout.nb_streams;s++)
    {
       OpusDecoder *dec;
-      int packet_offset, ret;
+      opus_int32 packet_offset;
+      int ret;
 
       dec = (OpusDecoder*)ptr;
       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
@@ -425,6 +426,7 @@
        case OPUS_GET_SAMPLE_RATE_REQUEST:
        case OPUS_GET_GAIN_REQUEST:
        case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
+       case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
        {
           OpusDecoder *dec;
           /* For int32* GET params, just query the first stream */
@@ -499,6 +501,7 @@
        }
        break;
        case OPUS_SET_GAIN_REQUEST:
+       case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
        {
           int s;
           /* This works for int32 params */
diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c
index e722e31..032fc00 100644
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -87,7 +87,6 @@
    int variable_duration;
    MappingType mapping_type;
    opus_int32 bitrate_bps;
-   float subframe_mem[3];
    /* Encoder states go here */
    /* then opus_val32 window_mem[channels*120]; */
    /* then opus_val32 preemph_mem[channels]; */
@@ -133,6 +132,29 @@
    return (opus_val32*)(void*)ptr;
 }
 
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
+static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
+{
+   int order_plus_one;
+   int acn_channels;
+   int nondiegetic_channels;
+
+   order_plus_one = isqrt32(nb_channels);
+   acn_channels = order_plus_one * order_plus_one;
+   nondiegetic_channels = nb_channels - acn_channels;
+
+   if (order_plus_one < 1 || order_plus_one > 15 ||
+       (nondiegetic_channels != 0 && nondiegetic_channels != 2))
+      return 0;
+
+   if (nb_streams)
+      *nb_streams = acn_channels + (nondiegetic_channels != 0);
+   if (nb_coupled_streams)
+      *nb_coupled_streams = nondiegetic_channels != 0;
+   return 1;
+}
+#endif
+
 static int validate_encoder_layout(const ChannelLayout *layout)
 {
    int s;
@@ -240,6 +262,7 @@
    int pos[8] = {0};
    int upsample;
    int frame_size;
+   int freq_size;
    opus_val16 channel_offset;
    opus_val32 bandE[21];
    opus_val16 maskLogE[3][21];
@@ -250,6 +273,7 @@
 
    upsample = resampling_factor(rate);
    frame_size = len*upsample;
+   freq_size = IMIN(960, frame_size);
 
    /* LM = log2(frame_size / 120) */
    for (LM=0;LM<celt_mode->maxLM;LM++)
@@ -258,7 +282,7 @@
 
    ALLOC(in, frame_size+overlap, opus_val32);
    ALLOC(x, len, opus_val16);
-   ALLOC(freq, frame_size, opus_val32);
+   ALLOC(freq, freq_size, opus_val32);
 
    channel_pos(channels, pos);
 
@@ -268,6 +292,9 @@
 
    for (c=0;c<channels;c++)
    {
+      int frame;
+      int nb_frames = frame_size/freq_size;
+      celt_assert(nb_frames*freq_size == frame_size);
       OPUS_COPY(in, mem+c*overlap, overlap);
       (*copy_channel_in)(x, 1, pcm, channels, c, len);
       celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
@@ -277,25 +304,33 @@
          sum = celt_inner_prod(in, in, frame_size+overlap, 0);
          /* This should filter out both NaNs and ridiculous signals that could
             cause NaNs further down. */
-         if (!(sum < 1e9f) || celt_isnan(sum))
+         if (!(sum < 1e18f) || celt_isnan(sum))
          {
             OPUS_CLEAR(in, frame_size+overlap);
             preemph_mem[c] = 0;
          }
       }
 #endif
-      clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window,
-            overlap, celt_mode->maxLM-LM, 1, arch);
-      if (upsample != 1)
+      OPUS_CLEAR(bandE, 21);
+      for (frame=0;frame<nb_frames;frame++)
       {
-         int bound = len;
-         for (i=0;i<bound;i++)
-            freq[i] *= upsample;
-         for (;i<frame_size;i++)
-            freq[i] = 0;
-      }
+         opus_val32 tmpE[21];
+         clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window,
+               overlap, celt_mode->maxLM-LM, 1, arch);
+         if (upsample != 1)
+         {
+            int bound = freq_size/upsample;
+            for (i=0;i<bound;i++)
+               freq[i] *= upsample;
+            for (;i<freq_size;i++)
+               freq[i] = 0;
+         }
 
-      compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
+         compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
+         /* If we have multiple frames, take the max energy. */
+         for (i=0;i<21;i++)
+            bandE[i] = MAX32(bandE[i], tmpE[i]);
+      }
       amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
       /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
       for (i=1;i<21;i++)
@@ -411,8 +446,8 @@
 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
    } else if (mapping_family==254)
    {
-      nb_streams=channels;
-      nb_coupled_streams=0;
+      if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
+         return 0;
 #endif
    } else
       return 0;
@@ -448,7 +483,6 @@
    st->layout.nb_channels = channels;
    st->layout.nb_streams = streams;
    st->layout.nb_coupled_streams = coupled_streams;
-   st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
    if (mapping_type != MAPPING_TYPE_SURROUND)
       st->lfe_stream = -1;
    st->bitrate_bps = OPUS_AUTO;
@@ -456,8 +490,16 @@
    st->variable_duration = OPUS_FRAMESIZE_ARG;
    for (i=0;i<st->layout.nb_channels;i++)
       st->layout.mapping[i] = mapping[i];
-   if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
+   if (!validate_layout(&st->layout))
       return OPUS_BAD_ARG;
+   if (mapping_type == MAPPING_TYPE_SURROUND &&
+       !validate_encoder_layout(&st->layout))
+      return OPUS_BAD_ARG;
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
+   if (mapping_type == MAPPING_TYPE_AMBISONICS &&
+       !validate_ambisonics(st->layout.nb_channels, NULL, NULL))
+      return OPUS_BAD_ARG;
+#endif
    ptr = (char*)st + align(sizeof(OpusMSEncoder));
    coupled_size = opus_encoder_get_size(2);
    mono_size = opus_encoder_get_size(1);
@@ -553,10 +595,12 @@
    } else if (mapping_family==254)
    {
       int i;
-      *streams=channels;
-      *coupled_streams=0;
-      for(i=0;i<channels;i++)
-         mapping[i] = i;
+      if (!validate_ambisonics(channels, streams, coupled_streams))
+         return OPUS_BAD_ARG;
+      for(i = 0; i < (*streams - *coupled_streams); i++)
+         mapping[i] = i + (*coupled_streams * 2);
+      for(i = 0; i < *coupled_streams * 2; i++)
+         mapping[i + (*streams - *coupled_streams)] = i;
 #endif
    } else
       return OPUS_UNIMPLEMENTED;
@@ -672,58 +716,59 @@
    int lfe_offset;
    int coupled_ratio; /* Q8 */
    int lfe_ratio;     /* Q8 */
+   int nb_lfe;
+   int nb_uncoupled;
+   int nb_coupled;
+   int nb_normal;
+   opus_int32 channel_offset;
+   opus_int32 bitrate;
+   int total;
 
-   if (st->bitrate_bps > st->layout.nb_channels*40000)
-      stream_offset = 20000;
-   else
-      stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
-   stream_offset += 60*(Fs/frame_size-50);
-   /* We start by giving each stream (coupled or uncoupled) the same bitrate.
+   nb_lfe = (st->lfe_stream!=-1);
+   nb_coupled = st->layout.nb_coupled_streams;
+   nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
+   nb_normal = 2*nb_coupled + nb_uncoupled;
+
+   /* Give each non-LFE channel enough bits per channel for coding band energy. */
+   channel_offset = 40*IMAX(50, Fs/frame_size);
+
+   if (st->bitrate_bps==OPUS_AUTO)
+   {
+      bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
+   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
+   {
+      bitrate = nb_normal*300000 + nb_lfe*128000;
+   } else {
+      bitrate = st->bitrate_bps;
+   }
+
+   /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
+      total rate for the non-energy part to avoid problems at really low rate. */
+   lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
+
+   /* We give each stream (coupled or uncoupled) a starting bitrate.
       This models the main saving of coupled channels over uncoupled. */
-   /* The LFE stream is an exception to the above and gets fewer bits. */
-   lfe_offset = 3500 + 60*(Fs/frame_size-50);
-   /* Coupled streams get twice the mono rate after the first 20 kb/s. */
+   stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
+   stream_offset = IMAX(0, IMIN(20000, stream_offset));
+
+   /* Coupled streams get twice the mono rate after the offset is allocated. */
    coupled_ratio = 512;
    /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
    lfe_ratio = 32;
 
-   /* Compute bitrate allocation between streams */
-   if (st->bitrate_bps==OPUS_AUTO)
-   {
-      channel_rate = Fs+60*Fs/frame_size;
-   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
-   {
-      channel_rate = 300000;
-   } else {
-      int nb_lfe;
-      int nb_uncoupled;
-      int nb_coupled;
-      int total;
-      nb_lfe = (st->lfe_stream!=-1);
-      nb_coupled = st->layout.nb_coupled_streams;
-      nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
-      total = (nb_uncoupled<<8)         /* mono */
-            + coupled_ratio*nb_coupled /* stereo */
-            + nb_lfe*lfe_ratio;
-      channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total;
-   }
-#ifndef FIXED_POINT
-   if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
-   {
-      opus_int32 bonus;
-      bonus = 60*(Fs/frame_size-50);
-      channel_rate += bonus;
-   }
-#endif
+   total = (nb_uncoupled<<8)         /* mono */
+         + coupled_ratio*nb_coupled /* stereo */
+         + nb_lfe*lfe_ratio;
+   channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
 
    for (i=0;i<st->layout.nb_streams;i++)
    {
       if (i<st->layout.nb_coupled_streams)
-         rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
+         rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
       else if (i!=st->lfe_stream)
-         rate[i] = stream_offset+channel_rate;
+         rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
       else
-         rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
+         rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
    }
 }
 
@@ -736,47 +781,72 @@
       )
 {
    int i;
-   int non_mono_rate;
    int total_rate;
+   int directional_rate;
+   int nondirectional_rate;
+   int leftover_bits;
 
-   /* The mono channel gets (rate_ratio_num / rate_ratio_den) times as many bits
-    * as all other channels */
+   /* Each nondirectional channel gets (rate_ratio_num / rate_ratio_den) times
+    * as many bits as all other ambisonics channels.
+    */
    const int rate_ratio_num = 4;
    const int rate_ratio_den = 3;
-   const int num_channels = st->layout.nb_streams;
+   const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
+   const int nb_nondirectional_channels = st->layout.nb_coupled_streams * 2 + 1;
+   const int nb_directional_channels = st->layout.nb_streams - 1;
 
    if (st->bitrate_bps==OPUS_AUTO)
    {
-      total_rate = num_channels * (20000 + st->layout.nb_streams*(Fs+60*Fs/frame_size));
+      total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
+         (Fs+60*Fs/frame_size) + st->layout.nb_streams * 15000;
    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
    {
-      total_rate = num_channels * 320000;
-   } else {
+      total_rate = nb_channels * 320000;
+   } else
+   {
       total_rate = st->bitrate_bps;
    }
 
-   /* Let y be the non-mono rate and let p, q be integers such that the mono
-    * channel rate is (p/q) * y.
+   /* Let y be the directional rate, m be the num of nondirectional channels
+    *   m = (s + 1)
+    * and let p, q be integers such that the nondirectional rate is
+    *   m_rate = (p / q) * y
     * Also let T be the total bitrate to allocate. Then
-    *   (n - 1) y + (p/q) y = T
-    *   y = (T q) / (qn - q + p)
+    *   T = (n - m) * y + m * m_rate
+    * Solving for y,
+    *   y = (q * T) / (m * (p - q) + n * q)
     */
-   non_mono_rate =
-         total_rate * rate_ratio_den
-         / (rate_ratio_den*num_channels + rate_ratio_num - rate_ratio_den);
+   directional_rate =
+      total_rate * rate_ratio_den
+      / (nb_nondirectional_channels * (rate_ratio_num - rate_ratio_den)
+       + nb_channels * rate_ratio_den);
 
-#ifndef FIXED_POINT
-   if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
-   {
-      opus_int32 bonus = 60*(Fs/frame_size-50);
-      non_mono_rate += bonus;
-   }
-#endif
+   /* Calculate the nondirectional rate.
+    *   m_rate = y * (p / q)
+    */
+   nondirectional_rate = directional_rate * rate_ratio_num / rate_ratio_den;
 
-   rate[0] = total_rate - (num_channels - 1) * non_mono_rate;
-   for (i=1;i<st->layout.nb_streams;i++)
+   /* Calculate the leftover from truncation error.
+    *   leftover = T - y * (n - m) - m_rate * m
+    * Place leftover bits in omnidirectional channel.
+    */
+   leftover_bits = total_rate
+      - directional_rate * nb_directional_channels
+      - nondirectional_rate * nb_nondirectional_channels;
+
+   /* Calculate rates for each channel */
+   for (i = 0; i < st->layout.nb_streams; i++)
    {
-      rate[i] = non_mono_rate;
+      if (i < st->layout.nb_coupled_streams)
+      {
+         rate[i] = nondirectional_rate * 2;
+      } else if (i == st->layout.nb_coupled_streams)
+      {
+         rate[i] = nondirectional_rate + leftover_bits;
+      } else
+      {
+         rate[i] = directional_rate;
+      }
    }
 }
 #endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
@@ -812,8 +882,8 @@
    return rate_sum;
 }
 
-/* Max size in case the encoder decides to return three frames */
-#define MS_FRAME_TMP (3*1275+7)
+/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
+#define MS_FRAME_TMP (6*1275+12)
 static int opus_multistream_encode_native
 (
     OpusMSEncoder *st,
@@ -859,32 +929,8 @@
    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
    opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
 
-   {
-      opus_int32 delay_compensation;
-      int channels;
-
-      channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
-      opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
-      delay_compensation -= Fs/400;
-      frame_size = compute_frame_size(pcm, analysis_frame_size,
-            st->variable_duration, channels, Fs, st->bitrate_bps,
-            delay_compensation, downmix
-#ifndef DISABLE_FLOAT_API
-            , st->subframe_mem
-#endif
-            );
-   }
-
-   if (400*frame_size < Fs)
-   {
-      RESTORE_STACK;
-      return OPUS_BAD_ARG;
-   }
-   /* Validate frame_size before using it to allocate stack space.
-      This mirrors the checks in opus_encode[_float](). */
-   if (400*frame_size != Fs && 200*frame_size != Fs &&
-       100*frame_size != Fs &&  50*frame_size != Fs &&
-        25*frame_size != Fs &&  50*frame_size != 3*Fs)
+   frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
+   if (frame_size <= 0)
    {
       RESTORE_STACK;
       return OPUS_BAD_ARG;
@@ -892,6 +938,9 @@
 
    /* Smallest packet the encoder can produce. */
    smallest_packet = st->layout.nb_streams*2-1;
+   /* 100 ms needs an extra byte per stream for the ToC. */
+   if (Fs/frame_size == 10)
+     smallest_packet += st->layout.nb_streams;
    if (max_data_bytes < smallest_packet)
    {
       RESTORE_STACK;
@@ -1013,6 +1062,9 @@
       curr_max = max_data_bytes - tot_size;
       /* Reserve one byte for the last stream and two for the others */
       curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
+      /* For 100 ms, reserve an extra byte per stream for the ToC */
+      if (Fs/frame_size == 10)
+        curr_max -= st->layout.nb_streams-s-1;
       curr_max = IMIN(curr_max,MS_FRAME_TMP);
       /* Repacketizer will add one or two bytes for self-delimited frames */
       if (s != st->layout.nb_streams-1) curr_max -=  curr_max>253 ? 2 : 1;
@@ -1161,9 +1213,11 @@
    case OPUS_SET_BITRATE_REQUEST:
    {
       opus_int32 value = va_arg(ap, opus_int32);
-      if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
+      if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
       {
-         goto bad_arg;
+         if (value <= 0)
+            goto bad_arg;
+         value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
       }
       st->bitrate_bps = value;
    }
@@ -1206,6 +1260,7 @@
    case OPUS_GET_INBAND_FEC_REQUEST:
    case OPUS_GET_FORCE_CHANNELS_REQUEST:
    case OPUS_GET_PREDICTION_DISABLED_REQUEST:
+   case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
    {
       OpusEncoder *enc;
       /* For int32* GET params, just query the first stream */
@@ -1252,6 +1307,7 @@
    case OPUS_SET_FORCE_MODE_REQUEST:
    case OPUS_SET_FORCE_CHANNELS_REQUEST:
    case OPUS_SET_PREDICTION_DISABLED_REQUEST:
+   case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
    {
       int s;
       /* This works for int32 params */
@@ -1313,7 +1369,6 @@
    case OPUS_RESET_STATE:
    {
       int s;
-      st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
       if (st->mapping_type == MAPPING_TYPE_SURROUND)
       {
          OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
diff --git a/src/opus_private.h b/src/opus_private.h
index 3b62eed..a731cc5 100644
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -92,14 +92,6 @@
 
 opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs);
 
-opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
-      int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
-      int delay_compensation, downmix_func downmix
-#ifndef DISABLE_FLOAT_API
-      , float *subframe_mem
-#endif
-      );
-
 opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
       unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
       const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
diff --git a/tests/opus_decode_fuzzer.c b/tests/opus_decode_fuzzer.c
new file mode 100644
index 0000000..4b4a3f3
--- /dev/null
+++ b/tests/opus_decode_fuzzer.c
@@ -0,0 +1,125 @@
+/* Copyright (c) 2017 Google Inc. */
+/*
+   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
+
+#include <stdlib.h>
+#include <string.h>
+#include "opus.h"
+#include "opus_types.h"
+
+#define MAX_FRAME_SAMP 5760
+#define MAX_PACKET 1500
+
+/* 4 bytes: packet length, 4 bytes: encoder final range */
+#define SETUP_BYTE_COUNT 8
+
+typedef struct {
+    int fs;
+    int channels;
+} TocInfo;
+
+static void ParseToc(const uint8_t *toc, TocInfo *const info) {
+    const int samp_freqs[5] = {8000, 12000, 16000, 24000, 48000};
+    const int bandwidth = opus_packet_get_bandwidth(toc);
+
+    info->fs = samp_freqs[bandwidth - OPUS_BANDWIDTH_NARROWBAND];
+    info->channels = opus_packet_get_nb_channels(toc);
+}
+
+/* Treats the input data as concatenated packets encoded by opus_demo,
+ * structured as
+ *    bytes 0..3: packet length
+ *    bytes 4..7: encoder final range
+ *    bytes 8+  : Opus packet, including ToC
+ */
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+    OpusDecoder *dec;
+    opus_int16 *pcm;
+    uint8_t *packet;
+    TocInfo toc;
+    int i, err;
+
+    /* Not enough data to setup the decoder (+1 for the ToC) */
+    if (size < SETUP_BYTE_COUNT + 1) {
+        return 0;
+    }
+
+    /* Create decoder based on info from the first ToC available */
+    ParseToc(&data[SETUP_BYTE_COUNT], &toc);
+
+    dec = opus_decoder_create(toc.fs, toc.channels, &err);
+    if (err != OPUS_OK | dec == NULL) {
+        return 0;
+    }
+
+    pcm = (opus_int16*) malloc(sizeof(*pcm) * MAX_FRAME_SAMP * toc.channels);
+    packet = (uint8_t*) calloc(MAX_PACKET, sizeof(*packet));
+
+    i = 0;
+    while (1) {
+        int len, fec;
+
+        if (i + SETUP_BYTE_COUNT >= size) {
+            break;
+        }
+
+        len = (opus_uint32) data[i    ] << 24 |
+              (opus_uint32) data[i + 1] << 16 |
+              (opus_uint32) data[i + 2] <<  8 |
+              (opus_uint32) data[i + 3];
+        if (len > MAX_PACKET || len < 0) {
+            break;
+        }
+
+        /* Bytes 4..7 represent encoder final range, but are unused here.
+         * Instead, byte 4 is repurposed to determine if FEC is used. */
+        fec = data[i + 4] & 1;
+
+        /* Lost packet */
+        if (len == 0) {
+            int frame_size;
+            opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&frame_size));
+            (void) opus_decode(dec, NULL, size, pcm, frame_size, fec);
+        } else {
+            if (i + SETUP_BYTE_COUNT + len > size) {
+                break;
+            }
+            memcpy(pcm, &data[i + SETUP_BYTE_COUNT], len);
+            (void) opus_decode(dec, data, size, pcm, MAX_FRAME_SAMP, fec);
+        }
+
+        i += SETUP_BYTE_COUNT + len;
+    }
+
+    opus_decoder_destroy(dec);
+    free(pcm);
+    free(packet);
+
+    return 0;
+}
diff --git a/tests/opus_decode_fuzzer.options b/tests/opus_decode_fuzzer.options
new file mode 100644
index 0000000..e5ae71b
--- /dev/null
+++ b/tests/opus_decode_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 1000000
diff --git a/tests/opus_encode_regressions.c b/tests/opus_encode_regressions.c
new file mode 100644
index 0000000..2923473
--- /dev/null
+++ b/tests/opus_encode_regressions.c
@@ -0,0 +1,1035 @@
+/* Copyright (c) 2016 Mark Harris, 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
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdint.h>
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+#include "opus_multistream.h"
+#include "opus.h"
+#include "test_opus_common.h"
+
+
+static int celt_ec_internal_error(void)
+{
+    OpusMSEncoder *enc;
+    int err;
+    unsigned char data[2460];
+    int streams;
+    int coupled_streams;
+    unsigned char mapping[1];
+
+    enc = opus_multistream_surround_encoder_create(16000, 1, 1, &streams,
+        &coupled_streams, mapping, OPUS_APPLICATION_VOIP, &err);
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(OPUS_AUTO));
+    {
+        static const short pcm[320] =
+        {
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,  1792,  1799,  1799,
+              1799,  1799,  1799,  1799,  1799,  1799,  1799,  1799,  1799,
+              1799,  1799,  1799,  1799,  1799,     0, 25600,  1799,  1799,
+              1799,  1799,  1799,  1799,  1799,  1799,  1799,  1799,  1799,
+              1799,  1799,  1799,  1799,     7,     0,   255,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0, 32767,    -1,
+                 0,     0,     0,   100,     0, 16384,     0,     0,     0,
+                 0,     0,     0,     4,     0,     0,  -256,   255,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,-32768,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,   128,     0,     0,     0,     0,
+                 0,     0,     0,     0,  -256,     0,     0,    32,     0,
+                 0,     0,     0,     0,     0,     0,  4352,     4,   228,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,  5632,     0,     0,
+                 0,     0,-32768,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,   256,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+             -3944, 10500,  4285, 10459, -6474, 10204, -6539, 11601, -6824,
+             13385, -7142, 13872,-11553, 13670, -7725, 13463, -6887,  7874,
+             -5580, 12600, -4964, 12480,  3254, 11741, -4210,  9741, -3155,
+              7558, -5468,  5431, -1073,  3641, -1304,     0,    -1,   343,
+                26,     0,     0,   150,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,  1799,  1799,  1799,  1799,  1799, -2553,
+                 7,  1792,  1799,  1799,  1799,  1799,  1799,  1799,  1799,
+              1799,  1799,  1799,  1799, -9721
+        };
+        err = opus_multistream_encode(enc, pcm, 320, data, 2460);
+        assert(err > 0);
+    }
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130));
+    {
+        static const short pcm[160] =
+        {
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9526, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, 25600, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510
+        };
+        err = opus_multistream_encode(enc, pcm, 160, data, 2460);
+        assert(err > 0);
+    }
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130));
+    {
+        static const short pcm[160] =
+        {
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9494, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510
+        };
+        err = opus_multistream_encode(enc, pcm, 160, data, 2460);
+        assert(err > 0);
+    }
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130));
+    {
+        static const short pcm[160] =
+        {
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9479, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510,
+             -9510, -9510, -9510, -9510, -9510, -9510, -9510
+        };
+        err = opus_multistream_encode(enc, pcm, 160, data, 2460);
+        assert(err > 0);
+    }
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130));
+    {
+        static const short pcm[160] =
+        {
+             -9510, -9510,  1799,  1799,  1799,  1799,  1799,  1799,  1799,
+              1799,  1799,  1799,  1799,  1799,  1799,  1799,  1799,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+              -256,   255,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,     0,     0,     0,   128,     0,
+                 0,     0,     0,     0,     0,     0,     0,     0,     0,
+                 0,    32,     0,     0,     0,     0,     0,     0,     0,
+              4352,     4,     0,     0,     0,     0,     0,     0,     0,
+                 0,     0,     0,     0,   148,     0,     0,     0,     0,
+              5632
+        };
+        err = opus_multistream_encode(enc, pcm, 160, data, 2460);
+        assert(err > 0);
+    }
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(12));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(41));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(21425));
+    {
+        static const short pcm[40] =
+        {
+             10459, -6474, 10204, -6539, 11601, -6824, 13385, -7142, 13872,
+            -11553, 13670, -7725, 13463, -6887, 12482, -5580, 12600, -4964,
+             12480,  3254, 11741, -4210,  9741, -3155,  7558, -5468,  5431,
+             -1073,  3641, -1304,     0,    -1,   343,    26,     0,     0,
+                 0,     0,  -256,   226
+        };
+        err = opus_multistream_encode(enc, pcm, 40, data, 2460);
+        assert(err > 0);
+        /* returns -3 */
+    }
+    opus_multistream_encoder_destroy(enc);
+    return 0;
+}
+
+static int mscbr_encode_fail10(void)
+{
+    OpusMSEncoder *enc;
+    int err;
+    unsigned char data[627300];
+    static const unsigned char mapping[255] =
+    {
+          0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
+         17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+         34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+         51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+         68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+         85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,
+        102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,
+        119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
+        136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,
+        153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,
+        170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
+        187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,
+        204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,
+        221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,
+        238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254
+    };
+
+    enc = opus_multistream_encoder_create(8000, 255, 254, 1, mapping,
+        OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err);
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(2));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(14));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(57));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(3642675));
+    {
+        static const short pcm[20*255] =
+        {
+                 0
+        };
+        err = opus_multistream_encode(enc, pcm, 20, data, 627300);
+        assert(err > 0);
+        /* returns -1 */
+    }
+    opus_multistream_encoder_destroy(enc);
+    return 0;
+}
+
+static int mscbr_encode_fail(void)
+{
+    OpusMSEncoder *enc;
+    int err;
+    unsigned char data[472320];
+    static const unsigned char mapping[192] =
+    {
+          0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
+         17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+         34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+         51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+         68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+         85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,
+        102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,
+        119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
+        136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,
+        153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,
+        170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,
+        187,188,189,190,191
+    };
+
+    enc = opus_multistream_encoder_create(8000, 192, 189, 3, mapping,
+        OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err);
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(15360));
+    {
+        static const short pcm[20*192] =
+        {
+                 0
+        };
+        err = opus_multistream_encode(enc, pcm, 20, data, 472320);
+        assert(err > 0);
+        /* returns -1 */
+    }
+    opus_multistream_encoder_destroy(enc);
+    return 0;
+}
+
+static int surround_analysis_uninit(void)
+{
+    OpusMSEncoder *enc;
+    int err;
+    unsigned char data[7380];
+    int streams;
+    int coupled_streams;
+    unsigned char mapping[3];
+
+    enc = opus_multistream_surround_encoder_create(24000, 3, 1, &streams,
+        &coupled_streams, mapping, OPUS_APPLICATION_AUDIO, &err);
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(84315));
+    {
+        static const short pcm[960*3] =
+        {
+             -6896,  4901, -6158,  4120, -5164,  3631, -4442,  3153, -4070,
+              3349, -4577,  4474, -5541,  5058, -6701,  3881, -7933,  1863,
+             -8041,   697, -6738,-31464, 14330,-12523,  4096, -6130, 29178,
+              -250,-21252, 10467, 16907, -3359, -6644, 31965, 14607,-21544,
+            -32497, 24020, 12557,-26926,-18421, -1842, 24587, 19659,  4878,
+             10954, 23060,  8907,-10215,-16179, 31772,-11825,-15590,-23089,
+             17173,-25903,-17387, 11733,  4884, 10204,-16476,-14367,   516,
+             20453,-16898, 20967,-23813,   -20, 22011,-17167,  9459, 32499,
+            -25855,  -523, -3883,  -390, -4206,   634, -3767,  2325, -2751,
+              3115, -2392,  2746, -2173,  2317, -1147,  2326, 23142, 11314,
+            -15350,-24529,  3026,  6146,  2150,  2476,  1105,  -830,  1775,
+             -3425,  3674,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+              4293,-14023,  3879,-15553,  3158,-16161,  2629, 18433,-12535,
+             -6645,-20735,-32763,-13824,-20992, 25859, 13052, -8731,  2292,
+             -3860, 24049, 10225,-19220, 10478,-22294, 22773, 28137, 13816,
+             30953,-25863,-24598, 16888,-14612,-28942, 20974,-27397,-18944,
+            -18690, 20991,-16638,  5632,-14330, 28911,-25594, 17408, 29958,
+              -517,-20984, -1800, 11281,  9977,-21221,-14854, 23840, -9477,
+              3362,-12805,-22493, 32507,   156, 16384, -1163,  2301, -1874,
+              4600, -1748,  6950, 16557,  8192, -7372, -1033, -3278,  2806,
+             20275,  3317,  -717,  9792,  -767,  9099,  -613,  8362,  5027,
+              7774,  2597,  8549,  5278,  8743,  9343,  6940, 13038,  4826,
+             14086,  2964, 13215,  1355, 11596,   455,  9850,  -519, 10680,
+             -2287, 12551, -3736, 13639, -4291, 13790, -2722, 14544,  -866,
+             15050,  -304, 22833, -1196, 13520, -2063, 13051, -2317, 13066,
+             -2737, 13773, -2664, 14105, -3447, 13854, 24589, 24672, -5280,
+             10388, -4933,  7543, -4149,  3654, -1552,  1726,   661,    57,
+              2922,  -751,  3917,  8419,  3840, -5218,  3435,  5540, -1073,
+              4153, -6656,  1649,  -769, -7276,-13072,  6380, -7948, 20717,
+             18425, 17392, 14335,-18190, -1842, 24587, 19659, 11790, 10954,
+             23060,  8907,-10215,-16179, 31772,-11825,-15590,-23101, 17173,
+            -25903,-17387, 11733,  4884, 10192,-16627,-14367,   516, 20453,
+            -16898, 20967,-23813,   -20, 22011,-17167,  9468, 32499,-25607,
+              -523, -3883,  -390, -4206,   634, -3767,  2325, -2751,  3115,
+             -2392,  2746, -2161,  2317, -1147,  2326, 23142, 11314,-15350,
+            -29137,  3026,-15056,  -491,-15170,  -386,-16015,  -641,-16505,
+              -930,-16206,  -717,-16175, -2839,-16374, -4558,-16237, -5207,
+            -15903, -6421,  6373, -1403,  5431, -1073,  3641, -1304, -4495,
+              -769, -7276,  2856, -7870,  3314, -8730,  3964,-10183,  4011,
+            -11135,  3421,-11727,  2966,-12360,  2818,-13472,  3660,-13805,
+              5162,-13478,  6434,-12840,  7335,-12420,  6865,-12349,  5541,
+            -11965,  5530,-10820,  5132, -9197,  3367, -7745,  1223, -6910,
+              -433, -6211, -1711, -4958, -1025, -3755,  -836, -3292, -1666,
+             -2661,-10755, 31472,-27906, 31471, 18690,  5617, 16649, 11253,
+            -22516,-17674,-31990,  3575,-31479,  5883, 26121, 12890, -6612,
+             12228,-11634,   523, 26136,-21496, 20745,-15868, -4100,-24826,
+             23282, 22798,   491, -1774, 15075,-27373,-13094,  6417,-29487,
+             14608, 10185, 16143, 22211, -8436,  4288, -8694,  2375,  3023,
+               486,  1455,   128,   202,   942,  -923,  2068, -1233,  -717,
+             -1042, -2167, 32255, -4632,   310, -4458, -3639, -5258,  2106,
+             -6857,  2681, -7497,  2765, -6601,  1945, -5219, 19154, -4877,
+               619, -5719, -1928, -6208,  -121,   593,   188,  1558, -4152,
+              1648,   156,  1604, -3664, -6862, -2851, -5112, -3600, -3747,
+             -5081, -4428, -5592, 20974,-27397,-18944,-18690, 20991,-17406,
+              5632,-14330, 28911, 15934, 15934, 15934, 15934, 15934, 15934,
+             15934, 15934, 15934, 15934, 15934, 15934,-25594, 17408, 29958,
+             -7173,-16888,  9098,  -613,  8362,   675,  7774,  2597,  8549,
+              5278,  8743,  9375,  6940, 13038,  4826, 14598,  7721,-24308,
+            -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24353,
+             28648,  6946, -1363, 12485, -1187, 26074,-25055, 10004,-24798,
+              7204, -4581, -9678,  1554, 10553,  3102, 12193,  2443, 11955,
+              1213, 10689, -1293,   921, -4173, 10709, -6049,  8815, -7128,
+              8147, -8308,  6847, -2977,  4920,-11447,-22426,-11794,  3514,
+            -10220,  3430, -7993,  1926, -7072,   327, -7569,  -608, -7605,
+              3695, -6271, -1579, -4877, -1419, -3103, -2197,   128, -3904,
+              3760, -5401,  4906, -6051,  4250, -6272,  3492, -6343,  3197,
+             -6397,  4041, -6341,  6255, -6381,  7905, 16504,     0, -6144,
+              8062, -5606,  8622, -5555,    -9,    -1,  7423,     0,     1,
+               238,  5148,  1309,  4700,  2218,  4403,  2573,  3568, 28303,
+              1758,  3454, -1247,  3434, -4912,  2862, -7844,  1718,-10095,
+               369,-12631,   128, -3904,  3632, -5401,  4906, -6051,  4250,
+             -6272,  3492, -6343,  3197, -6397,  4041, -6341,  6255, -6381,
+              7905, 16504,     0, -6144,  8062, -5606,  8622, -5555,  8439,
+             -3382,  7398, -1170,  6132,   238,  5148,  1309,  4700,  2218,
+              4403,  2573,  3568,  2703,  1758,  3454, -1247,  3434, -4912,
+              2862, -7844,  1718,-10095,   369,-12631,  -259,-14632,   234,
+            -15056,  -521,-15170,  -386,-16015,  -641,-16505,  -930,-16206,
+             -1209,-16146, -2839,-16374, -4558,-16218, -5207,-15903, -6421,
+            -15615, -6925,-14871, -6149,-13759, -5233,-12844, 18313, -4357,
+             -5696,  2804, 12992,-22802, -6720, -9770, -7088, -8998, 14330,
+            -12523, 14843, -6130, 29178,  -250,-27396, 10467, 16907, -3359,
+             -6644, 31965, 14607,-21544,-32497, 24020, 12557,-26926,  -173,
+              -129, -6401,  -130,-25089, -3841, -4916, -3048,   224,  -237,
+             -3969,  -189, -3529,  -535, -3464,-14863,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14395,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,     0, 32512,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,  9925,  -718,  9753,  -767,
+              9099,  -613,  8362,   675,  7774,  2597,  8549,  5278,  8743,
+              9375,  6940, 13038,  4826, 14598,  7721,-24308,-29905,-19703,
+            -17106,-16124, -3287,-26118,-19709,     0, 24353, 28648, 10274,
+            -11292,-29665,-16417, 24346, 14553, 18707, 26323, -4596,-17711,
+              5133, 26328,    13,-31168, 24583, 18404,-28927,-24350, 19453,
+             28642,  1019,-10777, -3079, 30188, -7686, 27635,-32521,-16384,
+             12528, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231,
+               780,-13849, 15119, 28647,  4888, -7705, 30750,    64,     0,
+             32488,  6687,-20758, 19745, -2070,-13792, -6414, 28188, -2821,
+             -4585,  7168,  7444, 23557,-21998, 13064,  3345, -4086,-28915,
+             -8694, 32262,  8461, 27387,-12275, 12012, 23563,-18719,-28410,
+             29144,-22271,  -562, -9986, -5434, 12288,  5573,-16642, 32448,
+             29182, 32705,-30723, 24255,-19716, 18368, -4357, -5696,  2804,
+             12992,-22802,-22080, -7701, -5183,   486, -3133, -5660, -1083,
+             16871,-28726,-11029,-30259, -1209,-16146, -2839,-16374, -4558,
+            -16218,-10523, 20697, -9500, -1316,  5431, -1073,  3641, -1304,
+              1649,  -769, -7276,  2856, -7870,  3314, -8730,  3964,-10183,
+              4011,-11135,  3421,-11727, 21398, 32767,    -1, 32486,    -1,
+              6301,-13071,  6380, -7948,    -1, 32767,   240, 14081, -5646,
+             30973, -3598,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,  8901,  9375,  6940, 13038,  4826, 14598,  7721,-24308,
+            -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361,
+             28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323,
+             -4440,-17711,  5133, 26328,-14579,-31008, 24583, 18404, 28417,
+            -24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635,
+            -32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321,
+             14605, 32231,   780,-13849, 15119, 28647,  4888, -7705,-15074,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,  8192,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14897,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -15931,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907, 26121, 12890,  2604,
+             12228,-11634, 12299,  5573,-16642, 32452, 29182, 32705,-30723,
+             24255,-19716, 13248,-11779, -5696,  2804, 12992,-27666,-22080,
+             -7701, -5183, -6682,-31464, 14330,-12523, 14843, -6130, 29178,
+               -18,-27396, 10467, 16907, -3359, -6644, 31965, 14607,-21544,
+            -32497, 24020, 12557,-26926,-18421,   706, 24587, 19659,  4878,
+             10954, 23060,  8907,-10215,-22579, 31772,-11825,-15590,-23089,
+             17173,-25903,-17387,  3285,  4884, 10204,-16627,-14367,   516,
+             20453,-16898, 20967,-23815,   -20, 22011,-17167,  9468, 32499,
+            -25607,  -523, -3883,  -390, -4206,   634, -3767,  2325, -2751,
+              3115, -2392,  2746, -2173,  2317, -1147,  2326, 23142, 11314,
+            -15130,-29137,  3026,  6146,  2150,  2476,  1105,  -830,  1775,
+             -3425,  3674, -5287,  4609, -7175,  4922, -9579,  4556,-12007,
+              4236,-14023,  3879,-15553,  3158,-16161,  2576, 18398,-12535,
+             -6645,-20735,-32763,-13824,-20992, 25859,  5372, 12040, 13307,
+             -4355,-30213,    -9, -6019, 14061,-31487,-13842, 30449, 15083,
+             14088, 31205,-18678,-12830, 14090,-26138,-25337,-11541, -3254,
+             27628,-22270, 30953,-16136,-30745, 20991,-17406,  5632,-14330,
+             28911,-25594, 17408,-20474, 13041, -8731,  2292, -3860, 24049,
+             10225,-19220, 10478, -4374, -1199,   148,  -330,   -74,   593,
+               188,  1558, -4152, 15984, 15934, 15934, 15934, 15934, 15934,
+             15934, 15934, 15934, 15934, 15934, 15934,  1598,   156,  1604,
+             -1163,  2278,-30018,-25821,-21763,-23776, 24066,  9502, 25866,
+            -25055, 10004,-24798,  7204, -4581, -9678,  1554, 10553,  3102,
+             12193,  2443, 11955,  1213, 10689, -1293,   921, -4173,  8661,
+             -6049,  8815,-21221,-14854, 23840, -9477,  8549,  5278,  8743,
+              9375,  6940, 13038,  4826, 14598,  7721,-24308,-29905,-19703,
+            -17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274,
+            -11292,-29665,-16417, 24346, 14580, 18707, 26323, -4410,-17711,
+              5133, 26328,-14579,-31008, 24583, 18404, 28417,-24350, 19453,
+             28642,-32513,-10777, -3079, 30188, -7686, 27635,-32521,-16384,
+            -20240, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231,
+               780,-13849, 15119, 28647,  4888, -7705, 30750,    64,     0,
+             32488,  6687,-20758, 19745, -2070,    -1,    -1,    28,   256,
+             -4608,  7168,  7444, 23557,-21998, 13064,  3345, -4086,-28915,
+             -8594, 32262,  8461, 27387,-12275, 12012, 23563,-18719,-28410,
+             29144,-22271,-32562,-16384, 12528, -6386, 10986, 23827,-25880,
+            -32752,-23321, 14605, 32231,   780,-13849, 15119, 28647,  4888,
+             -7705, 30750,    64,     0, 32488,  6687,-20758, 19745, -2070,
+            -13792, -6414, 28188, -2821, -4585,  7168,  7444, 23557,-21998,
+             13064,  3345, -4086,-28915, -8694, 32262,  8461, 27387,-12275,
+             12012, 23563,-18719,-28410, 29144,-22271,  -562, -9986, -5434,
+             12288, -2107,-16643, 32452, 29182, 32705,-30723, 24255,-19716,
+             18368, -4357, -5696,  2804, 12992,-22802,-22080, -7701, -5183,
+               486, -3133, -5660, -1083, 16871,-28726,-11029,-30259, -1209,
+            -16146, -2839,-16374, -4558,-16218,-10523, 20697, -9500, -1316,
+              5431, -1073,  3641, -1304,  1649,  -769, -7276,  2856, -7870,
+              3314, -8730,  3964,-10183,  4011,-11135,  3421,-11727, 21398,
+             32767,    -1, 32486,    -1,   -99,-13072,  6380, -7948,  4864,
+             32767, 17392, 14335, -5646, 30973, -3598,-10299,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14905,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-19771,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-16443,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-15931,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,    -1,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,  7877,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  -994, -7276,  2856, -7870,
+              3314, -8730,  3964,-10183,  4011,-11135,  3421,-11727, 21398,
+             32767,    -1, 32486,    -1,   -99,-13072,  6380, -7948,  4864,
+             32767, 17392, 14335, -5646, 30973, -3598,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14905,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,   197,     0,-14977,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907, 12838,  6653,   294,
+            -29699,-25821,-21763,-23776, 24066,  9502, 25866,-25055, 10004,
+            -24798,  7204, -4581, -9678,  1554, 10553,  3102, 12193,  2443,
+             11955,  1213, 10689, -1293,   921,   179,  8448, -6049,  8815,
+             -7128,  8147, -8308,  6847, -9889,  4920,-11447,  3174,-11794,
+              3514,-10220,  3430, 16384,  1926, -7072,   327, -7537,  -608,
+             -7605, -1169, -6397, -1579, -4877, -1419, -3103, -2197,   128,
+             -3904,  3632, -5401,  4906, -6051,  4250, -6272,  3492, -6343,
+              3197, -6397,  4041, -6341,  6255, -6381,  7905, 16504,     0,
+             -6144,  8062, -5606,  8622, -5555,  8439, -3382,  7398, -1170,
+              6132,   238,  5148,  1309,  4700,  2218,  4403,  2573,  3568,
+              2703,  1758,  3454, -1247,  3434, -4912,  2862, -7844,  1718,
+            -10095,   369,-12631,  -259,-14632,   234,-15056,  -491,-16194,
+              -386,-16015,  -641,-16505,  -930,-16206, -1209,-16146, -2839,
+            -16374, -4558,-16218, -5207,-15903, -6421,-15615, -6925,-14871,
+             -6149,-13759, -5233,-12844, 18313, -4357, -5696,  2804, 12992,
+            -22802, -6720, -9770, -7088, -8998, 14330,-12523, 14843, -6130,
+             29178,  -250,-27396, 10467, 16907, -3359, -6644, 31965, 14607,
+            -21544,-32497, 24020, 12557,-26926,  -173,  -129, -6401,  -130,
+            -25089, -3816, -4916, -3048,   -32,    -1, -3969,   256, -3529,
+              -535, -3464,-14863,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+             -1209,-16146, -2839,-16374, -4558,-16218,-10523, 20697, -9500,
+             -1316,  5431, -1073,  3641, -1304,  1649,  -769, -7276,  2856,
+             -7870,  3314, -8730,  3964,-10183,  4011,-11135,  3421,-11727,
+             21398, 32767,    -1, 32486,    -1,  6301,-13071,  6380, -7948,
+                -1, 32767,   240, 14081, -5646, 30973, -3598,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+             32767,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,  8901,  9375,  6940,
+             13038,  4826, 14598,  7721,-24308,-29905,-19703,-17106,-16124,
+             -3287,-26118,-19709,-10769, 24361, 28648, 10274,-11292,-29665,
+            -16417, 24346, 14580, 18707, 26323, -4440,-17711,  5133, 26328,
+            -14579,-31008, 24583, 18404, 28417,-24350, 19453, 28642,-32513,
+            -10777, -3079, 30188, -7686, 27635,-32521,-16384,-20240, -6386,
+             10986, 23827,-25880,-32752,-23321, 14605, 32231,   780,-13849,
+             15119, 28647,  4888, -7705,-15074,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,  8192,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14897,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-15931,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907, 26121, 12890,  2604, 12228,-11634, 12299,  5573,
+            -16642, 32452, 29182, 32705,-30723, 24255,-19716, 13248,-11779,
+             -5696,  2804, 12992,-27666,-22080, -7701, -5183, -6682,-31464,
+             14330,-12523, 14843, -6130, 29178,   -18,-27396, 10467, 16907,
+             -3359, -6644, 31965, 14607,-21544,-32497, 24020, 12557,-26926,
+            -18421,   706, 24587, 19659,  4878, 10954, 23060,  8907,-10215,
+            -22579, 31772,-11825,-15590,-23089, 17173,-25903,-17387,  3285,
+              4884, 10204,-16627,-14367,   516, 20453,-16898, 20967,-23815,
+               -20, 22011,-17167,  9468, 32499,-25607,  -523, -3883,  -390,
+             -4206,   634, -3767,  2325, -2751,  3115, -2392,  2746, -2173,
+              2317, -1147,  2326, 23142, 11314,-15130,-29137,  3026,  6146,
+              2150,  2476,  1105,  -830,  1775, -3425,  3674, -5287,  4609,
+             -7175,  4922, -9579,  4556,-12007,  4236,-14023,  3879,-15553,
+              3158,-16161,  2576, 18398,-12535, -6645,-20735,-32763,-13824,
+            -20992, 25859,  5372, 12040, 13307, -4355,-30213,    -9, -6019
+        };
+        err = opus_multistream_encode(enc, pcm, 960, data, 7380);
+        assert(err > 0);
+    }
+    opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(6));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(9));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(5));
+    opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(775410));
+    {
+        static const short pcm[1440*3] =
+        {
+             30449, 15083, 14088, 31205,-18678,-12830, 14090,-26138,-25337,
+            -11541, -3254, 27628,-22270, 30953,-16136,-30745, 20991,-17406,
+              5632,-14330, 28911,-25594, 17408,-20474, 13041, -8731,  2292,
+             -3860, 24049, 10225,-19220, 10478, -4374, -1199,   148,  -330,
+               -74,   593,   188,  1558, -4152, 15984, 15934, 15934, 15934,
+             15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934,  1598,
+               156,  1604, -1163,  2278,-30018,-25821,-21763,-23776, 24066,
+              9502, 25866,-25055, 10004,-24798,  7204, -4581, -9678,  1554,
+             10553,  3102, 12193,  2443, 11955,  1213, 10689, -1293,   921,
+             -4173,  8661, -6049,  8815,-21221,-14854, 23840, -9477,  8549,
+              5278,  8743,  9375,  6940, 13038,  4826, 14598,  7721,-24308,
+            -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361,
+             28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323,
+             -4410,-17711,  5133, 26328,-14579,-31008, 24583, 18404, 28417,
+            -24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635,
+            -32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321,
+             14605, 32231,   780,-13849, 15119, 28647,  4888, -7705, 30750,
+                64,     0, 32488,  6687,-20758, 19745, -2070,    -1,    -1,
+                28,   256, -4608,  7168,  7444, 23557,-21998, 13064,  3345,
+             -4086,-28915, -8594, 32262,  8461, 27387,-12275, 12012, 23563,
+            -18719,-28410, 29144,-22271,-32562,-16384, 12528, -6386, 10986,
+             23827,-25880,-32752,-23321, 14605, 32231,   780,-13849, 15119,
+             28647,  4888, -7705, 30750,    64,     0, 32488,  6687,-20758,
+             19745, -2070,-13792, -6414, 28188, -2821, -4585,  7168,  7444,
+             23557,-21998, 13064,  3345, -4086,-28915, -8694, 32262,  8461,
+            -14853,-14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14891,-14907,-14907,-14907,
+            -14907,-14907,  8901,  9375,  6940, 13038,  4826, 14598,  7721,
+            -24308,-29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769,
+             24361, 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707,
+             26323, -4440,-17711,  5133, 26328,-14579,-31008, 24583, 18404,
+             28417,-24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686,
+             27635,-32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,
+            -23321, 14605, 32231,   780,-13849, 15119, 28647,  4888, -7705,
+            -15074,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,  8192,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14897,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-15931,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907, 26121, 12890,
+              2604, 12228,-11634, 12299,  5573,-16642, 32452, 29182,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,  7710,
+              7710,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-10811,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14917,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14938,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,
+            -14907,-14907,-14907,-14907,  -571, -9986,   -58, 12542,-18491,
+             32507, 12838,  6653,   294,    -1,     0,-19968, 18368, -4357,
+             -5696,  2804, 12998,-22802,-22080, -7701, -5183,   486, -3133,
+             -5660, -1083, 13799,-28726,-11029,   205,-14848, 32464,    -1,
+              -129,-13072,  6380, -7948, 20717, 18425, 17392, 14335, -5646,
+             30973, -3598,  7188, -3867,  3055, -4247,  5597, -4011,-26427,
+               -11,-30418,  7922,  2614,   237, -5839,-27413,-17624,-29716,
+            -13539,   239, 20991, 18164, -4082,-16647,-27386, 19458, 20224,
+              4619, 19728, -7409,-18186,-25073, 27627,-23539, -7945,-31464,
+             14330,-12523,-22021, -7701, -5183,   486, -3133, -5660, -1083,
+             13799,-28726,-11029,   205,-14848, 32464,    -1,  -129,-13072,
+              6380, -7948, 20717, 18425, 17392, 14093, -5646, 30973, -3598,
+              7188, -3867,  3055,  3689, -5401,  4906, -6051,  4250, -6272,
+              3492, -6343,  3197, -6397,  4041, -6341,  6255, -6381,   239,
+             20991, 18164, -4082,-16647,-27386, 19458, 20224,  4619, 19728,
+             -7409,-18186,-25073, 27627,-23539, -7945,-31464, 14330,-12523,
+             14843, -6130, 30202,  -250,-28420, 10467, 16907, -3359, -6644,
+             31965,  3343,-11727,  2966,-12616,  3064,-13472,  6732,-12349,
+              5541,-11965,  5530,-10820, -1912, -3637, 32285, -4607,   310,
+            -32768,     0, -5258,  2106, -6857,  2681, -5449, -3606, -6717,
+             -5482, -3606, -1853,  4082, -7631, -9808, -1742, -2851, -5112,
+                64,  -868,-13546,-13365,-13365,-13365,-13365,-13365,-13365,
+            -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,
+            -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,
+            -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,
+            -13365,-13365,-13365,-13365,-13365,-13365,-13365,  7883, -2316,
+              9086, -3944, 10500,  4285, 10459, -6474, 10204, -6539, 11601,
+             -6824, 13385, -7142, 13872, -7457, 13670, -7725, 13463, -6887,
+             12482, -5580, 12600, -4964, 12480,  3254, 11741, -4210,-24819,
+             23282, 22798,   491, -1774, -1073,  3641, -1304, 28928,  -250,
+            -27396,  6657, -8961, 22524, 19987, 10231,  1791,  8947,-32763,
+            -26385,-31227,  -792,-30461,  8926,  4866, 27863, 27756, 27756,
+             27756, 27756, 27756, 27756, 27756, 27756,  5630,-11070,-16136,
+             20671,-11530, 27328,  8179,  5059,-31503,-24379,-19472, 17863,
+            -29202, 22986,   -23,  8909,  8422, 10450
+        };
+        err = opus_multistream_encode(enc, pcm, 1440, data, 7380);
+        /* reads uninitialized data at src/opus_multistream_encoder.c:293 */
+        assert(err > 0);
+    }
+    opus_multistream_encoder_destroy(enc);
+    return 0;
+}
+
+static int ec_enc_shrink_assert(void)
+{
+    OpusEncoder *enc;
+    int err;
+    int data_len;
+    unsigned char data[2000];
+    static const short pcm1[960] = { 5140 };
+    static const short pcm2[2880] =
+    {
+          -256,-12033,     0, -2817,  6912,     0, -5359,  5200,  3061,
+             0, -2903,  5652, -1281,-24656,-14433,-24678,    32,-29793,
+          2870,     0,  4096,  5120,  5140,  -234,-20230,-24673,-24633,
+        -24673,-24705,     0,-32768,-25444,-25444,     0,-25444,-25444,
+           156,-20480, -7948, -5920, -7968, -7968,   224,     0, 20480,
+            11, 20496,    13, 20496,    11,-20480,  2292,-20240,   244,
+         20480,    11, 20496,    11,-20480,   244,-20240,  7156, 20456,
+          -246,-20243,   244,   128,   244, 20480,    11, 20496,    11,
+        -20480,   244,-20256,   244, 20480,   256,     0,  -246, 16609,
+          -176,     0, 29872, -4096, -2888,   516,  2896,  4096,  2896,
+        -20480, -3852, -2896, -1025,-31056,-14433,   244,  1792,  -256,
+        -12033,     0, -2817,     0,     0, -5359,  5200,  3061,    16,
+         -2903,  5652, -1281,-24656,-14433,-24678,    32,-29793,  2870,
+             0,  4096,  5120,  5140,  -234,-20230,-24673,-24633,-24673,
+        -24705,     0,-32768,-25444,-25444,     0,-25444,-25444,   156,
+        -20480, -7973, -5920, -7968, -7968,   224,     0, 20480,    11,
+         20496,    11, 20496,    11,-20480,  2292,-20213,   244, 20480,
+            11, 20496,    11,-24698, -2873,     0,     7,    -1,   208,
+          -256,   244,     0,  4352, 20715, -2796,    11,-22272,  5364,
+          -234,-20230,-24673,-25913,  8351,-24832, 13963,    11,     0,
+            16,  5140,  5652, -1281,-24656,-14433,-24673, 32671,   159,
+             0,-25472,-25444,   156,-25600,-25444,-25444,     0, -2896,
+         -7968, -7960, -7968, -7968,     0,     0,  2896,  4096,  2896,
+          4096,  2896,     0, -2896, -4088, -2896,     0,  2896,     0,
+         -2896, -4096, -2896,    11,  2640, -4609, -2896,-32768, -3072,
+             0,  2896,  4096,  2896,     0, -2896, -4096, -2896,     0,
+            80,     1,  2816,     0, 20656,   255,-20480,   116,-18192
+    };
+    static const short pcm3[2880] = { 0 };
+
+    enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err);
+    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
+    opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(6));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000));
+    data_len = opus_encode(enc, pcm1, 960, data, 2000);
+    assert(data_len > 0);
+
+    opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
+    opus_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1));
+    opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
+    opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(15600));
+    data_len = opus_encode(enc, pcm2, 2880, data, 122);
+    assert(data_len > 0);
+
+    opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(27000));
+    data_len = opus_encode(enc, pcm3, 2880, data, 122); /* assertion failure */
+    assert(data_len > 0);
+
+    opus_encoder_destroy(enc);
+    return 0;
+}
+
+static int ec_enc_shrink_assert2(void)
+{
+    OpusEncoder *enc;
+    int err;
+    int data_len;
+    unsigned char data[2000];
+
+    enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err);
+    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(6));
+    opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
+    opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
+    opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(26));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(27000));
+    {
+        static const short pcm[960] = { 0 };
+        data_len = opus_encode(enc, pcm, 960, data, 2000);
+        assert(data_len > 0);
+    }
+    opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
+    {
+        static const short pcm[480] =
+        {
+            32767, 32767, 0, 0, 32767, 32767, 0, 0, 32767, 32767,
+            -32768, -32768, 0, 0, -32768, -32768, 0, 0, -32768, -32768
+        };
+        data_len = opus_encode(enc, pcm, 480, data, 19);
+        assert(data_len > 0);
+    }
+    opus_encoder_destroy(enc);
+    return 0;
+}
+
+static int silk_gain_assert(void)
+{
+    OpusEncoder *enc;
+    int err;
+    int data_len;
+    unsigned char data[1000];
+    static const short pcm1[160] = { 0 };
+    static const short pcm2[960] =
+    {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 32767
+    };
+
+    enc = opus_encoder_create(8000, 1, OPUS_APPLICATION_AUDIO, &err);
+    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(3));
+    opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000));
+    data_len = opus_encode(enc, pcm1, 160, data, 1000);
+    assert(data_len > 0);
+
+    opus_encoder_ctl(enc, OPUS_SET_VBR(0));
+    opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0));
+    opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND));
+    opus_encoder_ctl(enc, OPUS_SET_BITRATE(2867));
+    data_len = opus_encode(enc, pcm2, 960, data, 1000);
+    assert(data_len > 0);
+
+    opus_encoder_destroy(enc);
+    return 0;
+}
+
+void regression_test(void)
+{
+   fprintf(stderr, "Running simple tests for bugs that have been fixed previously\n");
+   celt_ec_internal_error();
+   mscbr_encode_fail10();
+   mscbr_encode_fail();
+   surround_analysis_uninit();
+   ec_enc_shrink_assert();
+   ec_enc_shrink_assert2();
+   silk_gain_assert();
+}
diff --git a/tests/run_vectors.sh b/tests/run_vectors.sh
index 1d447c4..dcb76cf 100755
--- a/tests/run_vectors.sh
+++ b/tests/run_vectors.sh
@@ -33,8 +33,8 @@
 #  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
+rm -f logs_mono.txt logs_mono2.txt
+rm -f logs_stereo.txt logs_stereo2.txt
 
 if [ "$#" -ne "3" ]; then
     echo "usage: run_vectors.sh <exec path> <vector path> <rate>"
@@ -48,51 +48,53 @@
 : ${OPUS_DEMO:=$CMD_PATH/opus_demo}
 : ${OPUS_COMPARE:=$CMD_PATH/opus_compare}
 
-if [ -d $VECTOR_PATH ]; then
-    echo Test vectors found in $VECTOR_PATH
+if [ -d "$VECTOR_PATH" ]; then
+    echo "Test vectors found in $VECTOR_PATH"
 else
-    echo No test vectors found
+    echo "No test vectors found"
     #Don't make the test fail here because the test vectors
     #will be distributed separately
     exit 0
 fi
 
-if [ ! -x $OPUS_COMPARE ]; then
-    echo ERROR: Compare program not found: $OPUS_COMPARE
+if [ ! -x "$OPUS_COMPARE" ]; then
+    echo "ERROR: Compare program not found: $OPUS_COMPARE"
     exit 1
 fi
 
-if [ -x $OPUS_DEMO ]; then
-    echo Decoding with $OPUS_DEMO
+if [ -x "$OPUS_DEMO" ]; then
+    echo "Decoding with $OPUS_DEMO"
 else
-    echo ERROR: Decoder not found: $OPUS_DEMO
+    echo "ERROR: Decoder not found: $OPUS_DEMO"
     exit 1
 fi
 
 echo "=============="
-echo Testing mono
+echo "Testing mono"
 echo "=============="
 echo
 
 for file in 01 02 03 04 05 06 07 08 09 10 11 12
 do
-    if [ -e $VECTOR_PATH/testvector$file.bit ]; then
-        echo Testing testvector$file
+    if [ -e "$VECTOR_PATH/testvector$file.bit" ]; then
+        echo "Testing testvector$file"
     else
-        echo Bitstream file not found: testvector$file.bit
+        echo "Bitstream file not found: testvector$file.bit"
     fi
-    if $OPUS_DEMO -d $RATE 1 $VECTOR_PATH/testvector$file.bit tmp.out >> logs_mono.txt 2>&1; then
-        echo successfully decoded
+    if "$OPUS_DEMO" -d "$RATE" 1 "$VECTOR_PATH/testvector$file.bit" tmp.out >> logs_mono.txt 2>&1; then
+        echo "successfully decoded"
     else
-        echo ERROR: decoding failed
+        echo "ERROR: decoding failed"
         exit 1
     fi
-    $OPUS_COMPARE -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_mono.txt 2>&1
+    "$OPUS_COMPARE" -r "$RATE" "$VECTOR_PATH/testvector${file}.dec" tmp.out >> logs_mono.txt 2>&1
     float_ret=$?
-    if [ "$float_ret" -eq "0" ]; then
-        echo output matches reference
+    "$OPUS_COMPARE" -r "$RATE" "$VECTOR_PATH/testvector${file}m.dec" tmp.out >> logs_mono2.txt 2>&1
+    float_ret2=$?
+    if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
+        echo "output matches reference"
     else
-        echo ERROR: output does not match reference
+        echo "ERROR: output does not match reference"
         exit 1
     fi
     echo
@@ -105,23 +107,25 @@
 
 for file in 01 02 03 04 05 06 07 08 09 10 11 12
 do
-    if [ -e $VECTOR_PATH/testvector$file.bit ]; then
-        echo Testing testvector$file
+    if [ -e "$VECTOR_PATH/testvector$file.bit" ]; then
+        echo "Testing testvector$file"
     else
-        echo Bitstream file not found: testvector$file
+        echo "Bitstream file not found: testvector$file"
     fi
-    if $OPUS_DEMO -d $RATE 2 $VECTOR_PATH/testvector$file.bit tmp.out >> logs_stereo.txt 2>&1; then
-        echo successfully decoded
+    if "$OPUS_DEMO" -d "$RATE" 2 "$VECTOR_PATH/testvector$file.bit" tmp.out >> logs_stereo.txt 2>&1; then
+        echo "successfully decoded"
     else
-        echo ERROR: decoding failed
+        echo "ERROR: decoding failed"
         exit 1
     fi
-    $OPUS_COMPARE -s -r $RATE $VECTOR_PATH/testvector$file.dec tmp.out >> logs_stereo.txt 2>&1
+    "$OPUS_COMPARE" -s -r "$RATE" "$VECTOR_PATH/testvector${file}.dec" tmp.out >> logs_stereo.txt 2>&1
     float_ret=$?
-    if [ "$float_ret" -eq "0" ]; then
-        echo output matches reference
+    "$OPUS_COMPARE" -s -r "$RATE" "$VECTOR_PATH/testvector${file}m.dec" tmp.out >> logs_stereo2.txt 2>&1
+    float_ret2=$?
+    if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
+        echo "output matches reference"
     else
-        echo ERROR: output does not match reference
+        echo "ERROR: output does not match reference"
         exit 1
     fi
     echo
@@ -129,6 +133,11 @@
 
 
 
-echo All tests have passed successfully
-grep quality logs_mono.txt | awk '{sum+=$4}END{print "Average mono quality is", sum/NR, "%"}'
-grep quality logs_stereo.txt | awk '{sum+=$4}END{print "Average stereo quality is", sum/NR, "%"}'
+echo "All tests have passed successfully"
+mono1=`grep quality logs_mono.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
+mono2=`grep quality logs_mono2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
+echo $mono1 $mono2 | awk '{if ($2 > $1) $1 = $2; print "Average mono quality is", $1, "%"}'
+
+stereo1=`grep quality logs_stereo.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
+stereo2=`grep quality logs_stereo2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
+echo $stereo1 $stereo2 | awk '{if ($2 > $1) $1 = $2; print "Average stereo quality is", $1, "%"}'
diff --git a/tests/test_opus_api.c b/tests/test_opus_api.c
index 489052d..1d00950 100644
--- a/tests/test_opus_api.c
+++ b/tests/test_opus_api.c
@@ -1383,6 +1383,15 @@
    err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_60_MS));
    if(err!=OPUS_OK)test_failed();
    cfgs++;
+   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_80_MS));
+   if(err!=OPUS_OK)test_failed();
+   cfgs++;
+   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_100_MS));
+   if(err!=OPUS_OK)test_failed();
+   cfgs++;
+   err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_120_MS));
+   if(err!=OPUS_OK)test_failed();
+   cfgs++;
    CHECK_SETGET(OPUS_SET_EXPERT_FRAME_DURATION(i),OPUS_GET_EXPERT_FRAME_DURATION(&i),0,-1,
          OPUS_FRAMESIZE_60_MS,OPUS_FRAMESIZE_ARG,
      "    OPUS_SET_EXPERT_FRAME_DURATION ............... OK.\n",
diff --git a/tests/test_opus_common.h b/tests/test_opus_common.h
index 66b9690..ff7f014 100644
--- a/tests/test_opus_common.h
+++ b/tests/test_opus_common.h
@@ -76,3 +76,5 @@
   abort();
 }
 #define test_failed() _test_failed(__FILE__, __LINE__);
+
+void regression_test(void);
diff --git a/tests/test_opus_decode.c b/tests/test_opus_decode.c
index 9c0eb9c..5197fa1 100644
--- a/tests/test_opus_decode.c
+++ b/tests/test_opus_decode.c
@@ -104,7 +104,7 @@
       int factor=48000/fsv[t>>1];
       for(fec=0;fec<2;fec++)
       {
-         int dur;
+         opus_int32 dur;
          /*Test PLC on a fresh decoder*/
          out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
          if(out_samples!=120/factor)test_failed();
@@ -135,7 +135,14 @@
          outbuf[0]=32749;
          out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);
          if(out_samples>0)test_failed();
+#if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wnonnull"
+#endif
          out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
+#if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
+#pragma GCC diagnostic pop
+#endif
          if(out_samples>0)test_failed();
          if(outbuf[0]!=32749)test_failed();
 
@@ -160,7 +167,7 @@
    /*Count code 0 tests*/
    for(i=0;i<64;i++)
    {
-      int dur;
+      opus_int32 dur;
       int j,expected[5*2];
       packet[0]=i<<2;
       packet[1]=255;
@@ -314,7 +321,7 @@
       if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
       for(t=0;t<5*2;t++)
       {
-         int dur;
+         opus_int32 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;
@@ -384,26 +391,26 @@
    {
       for (j=0;j<1024;j++)
       {
-        x[j]=(i&255)*(1/32.f)-4.f;
+        x[j]=(j&255)*(1/32.f)-4.f;
       }
       opus_pcm_soft_clip(&x[i],1024-i,1,s);
       for (j=i;j<1024;j++)
       {
-        if(x[i]>1.f)test_failed();
-        if(x[i]<-1.f)test_failed();
+        if(x[j]>1.f)test_failed();
+        if(x[j]<-1.f)test_failed();
       }
    }
    for(i=1;i<9;i++)
    {
       for (j=0;j<1024;j++)
       {
-        x[j]=(i&255)*(1/32.f)-4.f;
+        x[j]=(j&255)*(1/32.f)-4.f;
       }
       opus_pcm_soft_clip(x,1024/i,i,s);
       for (j=0;j<(1024/i)*i;j++)
       {
-        if(x[i]>1.f)test_failed();
-        if(x[i]<-1.f)test_failed();
+        if(x[j]>1.f)test_failed();
+        if(x[j]<-1.f)test_failed();
       }
    }
    opus_pcm_soft_clip(x,0,1,s);
@@ -436,7 +443,7 @@
       iseed=atoi(env_seed);
       env_used=1;
    }
-   else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);
+   else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
    Rw=Rz=iseed;
 
    oversion=opus_get_version_string();
diff --git a/tests/test_opus_encode.c b/tests/test_opus_encode.c
index 132d074..dae49c3 100644
--- a/tests/test_opus_encode.c
+++ b/tests/test_opus_encode.c
@@ -51,8 +51,8 @@
 #define SAMPLES (48000*30)
 #define SSAMPLES (SAMPLES/3)
 #define MAX_FRAME_SAMP (5760)
-
 #define PI (3.141592653589793238462643f)
+#define RAND_SAMPLE(a) (a[fast_rand() % sizeof(a)/sizeof(a[0])])
 
 void generate_music(short *buf, opus_int32 len)
 {
@@ -112,14 +112,169 @@
 }
 #endif
 
+int get_frame_size_enum(int frame_size, int sampling_rate)
+{
+   int frame_size_enum;
+
+   if(frame_size==sampling_rate/400)
+      frame_size_enum = OPUS_FRAMESIZE_2_5_MS;
+   else if(frame_size==sampling_rate/200)
+      frame_size_enum = OPUS_FRAMESIZE_5_MS;
+   else if(frame_size==sampling_rate/100)
+      frame_size_enum = OPUS_FRAMESIZE_10_MS;
+   else if(frame_size==sampling_rate/50)
+      frame_size_enum = OPUS_FRAMESIZE_20_MS;
+   else if(frame_size==sampling_rate/25)
+      frame_size_enum = OPUS_FRAMESIZE_40_MS;
+   else if(frame_size==3*sampling_rate/50)
+      frame_size_enum = OPUS_FRAMESIZE_60_MS;
+   else if(frame_size==4*sampling_rate/50)
+      frame_size_enum = OPUS_FRAMESIZE_80_MS;
+   else if(frame_size==5*sampling_rate/50)
+      frame_size_enum = OPUS_FRAMESIZE_100_MS;
+   else if(frame_size==6*sampling_rate/50)
+      frame_size_enum = OPUS_FRAMESIZE_120_MS;
+   else
+      test_failed();
+
+   return frame_size_enum;
+}
+
+void test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *dec, const char* debug_info)
+{
+   int samp_count = 0;
+   opus_int16 *inbuf;
+   unsigned char packet[MAX_PACKET+257];
+   int len;
+   opus_int16 *outbuf;
+   int out_samples;
+
+   /* Generate input data */
+   inbuf = (opus_int16*)malloc(sizeof(*inbuf)*SSAMPLES);
+   generate_music(inbuf, SSAMPLES/2);
+
+   /* Allocate memory for output data */
+   outbuf = (opus_int16*)malloc(sizeof(*outbuf)*MAX_FRAME_SAMP*3);
+
+   /* Encode data, then decode for sanity check */
+   do {
+      len = opus_encode(enc, &inbuf[samp_count*channels], frame_size, packet, MAX_PACKET);
+      if(len<0 || len>MAX_PACKET) {
+         fprintf(stderr,"%s\n",debug_info);
+         fprintf(stderr,"opus_encode() returned %d\n",len);
+         test_failed();
+      }
+
+      out_samples = opus_decode(dec, packet, len, outbuf, MAX_FRAME_SAMP, 0);
+      if(out_samples!=frame_size) {
+         fprintf(stderr,"%s\n",debug_info);
+         fprintf(stderr,"opus_decode() returned %d\n",out_samples);
+         test_failed();
+      }
+
+      samp_count += frame_size;
+   } while (samp_count < ((SSAMPLES/2)-MAX_FRAME_SAMP));
+
+   /* Clean up */
+   free(inbuf);
+   free(outbuf);
+}
+
+void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes)
+{
+   OpusEncoder *enc;
+   OpusDecoder *dec;
+   int i,j,err;
+
+   /* Parameters to fuzz. Some values are duplicated to increase their probability of being tested. */
+   int sampling_rates[5] = {8000, 12000, 16000, 24000, 48000};
+   int channels[2] = {1, 2};
+   int applications[3] = {OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY};
+   int bitrates[11] = {6000, 12000, 16000, 24000, 32000, 48000, 64000, 96000, 510000, OPUS_AUTO, OPUS_BITRATE_MAX};
+   int force_channels[4] = {OPUS_AUTO, OPUS_AUTO, 1, 2};
+   int use_vbr[3] = {0, 1, 1};
+   int vbr_constraints[3] = {0, 1, 1};
+   int complexities[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+   int max_bandwidths[6] = {OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_MEDIUMBAND,
+                            OPUS_BANDWIDTH_WIDEBAND, OPUS_BANDWIDTH_SUPERWIDEBAND,
+                            OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_FULLBAND};
+   int signals[4] = {OPUS_AUTO, OPUS_AUTO, OPUS_SIGNAL_VOICE, OPUS_SIGNAL_MUSIC};
+   int inband_fecs[3] = {0, 0, 1};
+   int packet_loss_perc[4] = {0, 1, 2, 5};
+   int lsb_depths[2] = {8, 24};
+   int prediction_disabled[3] = {0, 0, 1};
+   int use_dtx[2] = {0, 1};
+   int frame_sizes_ms_x2[9] = {5, 10, 20, 40, 80, 120, 160, 200, 240};  /* x2 to avoid 2.5 ms */
+   char debug_info[512];
+
+   for (i=0; i<num_encoders; i++) {
+      int sampling_rate = RAND_SAMPLE(sampling_rates);
+      int num_channels = RAND_SAMPLE(channels);
+      int application = RAND_SAMPLE(applications);
+
+      dec = opus_decoder_create(sampling_rate, num_channels, &err);
+      if(err!=OPUS_OK || dec==NULL)test_failed();
+
+      enc = opus_encoder_create(sampling_rate, num_channels, application, &err);
+      if(err!=OPUS_OK || enc==NULL)test_failed();
+
+      for (j=0; j<num_setting_changes; j++) {
+         int bitrate = RAND_SAMPLE(bitrates);
+         int force_channel = RAND_SAMPLE(force_channels);
+         int vbr = RAND_SAMPLE(use_vbr);
+         int vbr_constraint = RAND_SAMPLE(vbr_constraints);
+         int complexity = RAND_SAMPLE(complexities);
+         int max_bw = RAND_SAMPLE(max_bandwidths);
+         int sig = RAND_SAMPLE(signals);
+         int inband_fec = RAND_SAMPLE(inband_fecs);
+         int pkt_loss = RAND_SAMPLE(packet_loss_perc);
+         int lsb_depth = RAND_SAMPLE(lsb_depths);
+         int pred_disabled = RAND_SAMPLE(prediction_disabled);
+         int dtx = RAND_SAMPLE(use_dtx);
+         int frame_size_ms_x2 = RAND_SAMPLE(frame_sizes_ms_x2);
+         int frame_size = frame_size_ms_x2*sampling_rate/2000;
+         int frame_size_enum = get_frame_size_enum(frame_size, sampling_rate);
+         force_channel = IMIN(force_channel, num_channels);
+
+         sprintf(debug_info,
+                 "fuzz_encoder_settings: %d kHz, %d ch, application: %d, "
+                 "%d bps, force ch: %d, vbr: %d, vbr constraint: %d, complexity: %d, "
+                 "max bw: %d, signal: %d, inband fec: %d, pkt loss: %d%%, lsb depth: %d, "
+                 "pred disabled: %d, dtx: %d, (%d/2) ms\n",
+                 sampling_rate/1000, num_channels, application, bitrate,
+                 force_channel, vbr, vbr_constraint, complexity, max_bw, sig, inband_fec,
+                 pkt_loss, lsb_depth, pred_disabled, dtx, frame_size_ms_x2);
+
+         if(opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(force_channel)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_VBR(vbr)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(vbr_constraint)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(max_bw)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_SIGNAL(sig)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(inband_fec)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(pkt_loss)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(lsb_depth)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(pred_disabled)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_DTX(dtx)) != OPUS_OK) test_failed();
+         if(opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(frame_size_enum)) != OPUS_OK) test_failed();
+
+         test_encode(enc, num_channels, frame_size, dec, debug_info);
+      }
+
+      opus_encoder_destroy(enc);
+      opus_decoder_destroy(dec);
+   }
+}
+
 int run_test1(int no_fuzz)
 {
    static const int fsizes[6]={960*3,960*2,120,240,480,960};
    static const char *mstrings[3] = {"    LP","Hybrid","  MDCT"};
    unsigned char mapping[256] = {0,1,255};
    unsigned char db62[36];
-   opus_int32 i;
-   int rc,j,err;
+   opus_int32 i,j;
+   int rc,err;
    OpusEncoder *enc;
    OpusMSEncoder *MSenc;
    OpusDecoder *dec;
@@ -229,6 +384,7 @@
 
    if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed();
    if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(-2))!=OPUS_BAD_ARG)test_failed();
+   if(opus_encode(enc, inbuf, 500, packet, MAX_PACKET)!=OPUS_BAD_ARG)test_failed();
 
    for(rc=0;rc<3;rc++)
    {
@@ -335,7 +491,8 @@
          if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();
          count=i=0;
          do {
-            int pred,len,out_samples,frame_size,loss;
+            int len,out_samples,frame_size,loss;
+            opus_int32 pred;
             if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_PREDICTION_DISABLED(&pred))!=OPUS_OK)test_failed();
             if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PREDICTION_DISABLED((int)(fast_rand()&15)<(pred?11:4)))!=OPUS_OK)test_failed();
             frame_size=frame[j];
@@ -425,7 +582,7 @@
          the decoders in order to compare them. */
       if(opus_packet_parse(packet,len,&toc,frames,size,&payload_offset)<=0)test_failed();
       if((fast_rand()&1023)==0)len=0;
-      for(j=(frames[0]-packet);j<len;j++)for(jj=0;jj<8;jj++)packet[j]^=((!no_fuzz)&&((fast_rand()&1023)==0))<<jj;
+      for(j=(opus_int32)(frames[0]-packet);j<len;j++)for(jj=0;jj<8;jj++)packet[j]^=((!no_fuzz)&&((fast_rand()&1023)==0))<<jj;
       out_samples = opus_decode(dec_err[0], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);
       if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed();
       if((len>0&&out_samples!=frame_size))test_failed(); /*FIXME use lastframe*/
@@ -470,39 +627,74 @@
    return 0;
 }
 
+void print_usage(char* _argv[])
+{
+   fprintf(stderr,"Usage: %s [<seed>] [-fuzz <num_encoders> <num_settings_per_encoder>]\n",_argv[0]);
+}
+
 int main(int _argc, char **_argv)
 {
+   int args=1;
+   char * strtol_str=NULL;
    const char * oversion;
    const char * env_seed;
    int env_used;
-
-   if(_argc>2)
-   {
-      fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
-      return 1;
-   }
+   int num_encoders_to_fuzz=5;
+   int num_setting_changes=40;
 
    env_used=0;
    env_seed=getenv("SEED");
-   if(_argc>1)iseed=atoi(_argv[1]);
-   else if(env_seed)
-   {
+   if(_argc>1)
+      iseed=strtol(_argv[1], &strtol_str, 10);  /* the first input argument might be the seed */
+   if(strtol_str!=NULL && strtol_str[0]=='\0')   /* iseed is a valid number */
+      args++;
+   else if(env_seed) {
       iseed=atoi(env_seed);
       env_used=1;
    }
-   else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);
+   else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
    Rw=Rz=iseed;
 
+   while(args<_argc)
+   {
+      if(strcmp(_argv[args], "-fuzz")==0 && _argc==(args+3)) {
+         num_encoders_to_fuzz=strtol(_argv[args+1], &strtol_str, 10);
+         if(strtol_str[0]!='\0' || num_encoders_to_fuzz<=0) {
+            print_usage(_argv);
+            return EXIT_FAILURE;
+         }
+         num_setting_changes=strtol(_argv[args+2], &strtol_str, 10);
+         if(strtol_str[0]!='\0' || num_setting_changes<=0) {
+            print_usage(_argv);
+            return EXIT_FAILURE;
+         }
+         args+=3;
+      }
+      else {
+        print_usage(_argv);
+        return EXIT_FAILURE;
+      }
+   }
+
    oversion=opus_get_version_string();
    if(!oversion)test_failed();
    fprintf(stderr,"Testing %s encoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
    if(env_used)fprintf(stderr,"  Random seed set from the environment (SEED=%s).\n", env_seed);
 
+   regression_test();
+
    /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
      into the decoders. This is helpful because garbage data
      may cause the decoders to clip, which angers CLANG IOC.*/
    run_test1(getenv("TEST_OPUS_NOFUZZ")!=NULL);
 
+   /* Fuzz encoder settings online */
+   if(getenv("TEST_OPUS_NOFUZZ")==NULL) {
+      fprintf(stderr,"Running fuzz_encoder_settings with %d encoder(s) and %d setting change(s) each.\n",
+              num_encoders_to_fuzz, num_setting_changes);
+      fuzz_encoder_settings(num_encoders_to_fuzz, num_setting_changes);
+   }
+
    fprintf(stderr,"Tests completed successfully.\n");
 
    return 0;
diff --git a/update_version b/update_version
new file mode 100755
index 0000000..a999991
--- /dev/null
+++ b/update_version
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+# Creates and updates the package_version information used by configure.ac
+# (or other makefiles).  When run inside a git repository it will use the
+# version information that can be queried from it unless AUTO_UPDATE is set
+# to 'no'.  If no version is currently known it will be set to 'unknown'.
+#
+# If called with the argument 'release', the PACKAGE_VERSION will be updated
+# even if AUTO_UPDATE=no, but the value of AUTO_UPDATE shall be preserved.
+# This is used to force a version update whenever `make dist` is run.
+#
+# The exit status is 1 if package_version is not modified, else 0 is returned.
+#
+# This script should NOT be included in distributed tarballs, because if a
+# parent directory contains a git repository we do not want to accidentally
+# retrieve the version information from it instead.  Tarballs should ship
+# with only the package_version file.
+#
+# Ron <ron@debian.org>, 2012.
+
+SRCDIR=$(dirname $0)
+
+if [ -e "$SRCDIR/package_version" ]; then
+    . "$SRCDIR/package_version"
+fi
+
+if [ "$AUTO_UPDATE" = no ]; then
+    [ "$1" = release ] || exit 1
+else
+    AUTO_UPDATE=yes
+fi
+
+# We run `git status` before describe here to ensure that we don't get a false
+# -dirty from files that have been touched but are not actually altered in the
+# working dir.
+GIT_VERSION=$(cd "$SRCDIR" && git status > /dev/null 2>&1 \
+                           && git describe --tags --match 'v*' --dirty 2> /dev/null)
+GIT_VERSION=${GIT_VERSION#v}
+
+if [ -n "$GIT_VERSION" ]; then
+
+    [ "$GIT_VERSION" != "$PACKAGE_VERSION" ] || exit 1
+    PACKAGE_VERSION="$GIT_VERSION"
+
+elif [ -z "$PACKAGE_VERSION" ]; then
+    # No current package_version and no git ...
+    # We really shouldn't ever get here, because this script should only be
+    # included in the git repository, and should usually be export-ignored.
+    PACKAGE_VERSION="unknown"
+else
+    exit 1
+fi
+
+cat > "$SRCDIR/package_version" <<-EOF
+	# Automatically generated by update_version.
+	# This file may be sourced into a shell script or makefile.
+
+	# Set this to 'no' if you do not wish the version information
+	# to be checked and updated for every build.  Most people will
+	# never want to change this, it is an option for developers
+	# making frequent changes that they know will not be released.
+	AUTO_UPDATE=$AUTO_UPDATE
+
+	PACKAGE_VERSION="$PACKAGE_VERSION"
+EOF
diff --git a/version.mk b/version.mk
deleted file mode 100644
index 91c5105..0000000
--- a/version.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-# static version string; update manually every release.
-PACKAGE_VERSION = "1.1.4"
diff --git a/win32/.gitignore b/win32/.gitignore
new file mode 100644
index 0000000..c17feab
--- /dev/null
+++ b/win32/.gitignore
@@ -0,0 +1,26 @@
+# Visual Studio ignores
+[Dd]ebug/
+[Dd]ebugDLL/
+[Dd]ebugDLL_fixed/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleaseDLL/
+[Rr]eleaseDLL_fixed/
+[Rr]eleases/
+*.manifest
+*.lastbuildstate
+*.lib
+*.log
+*.idb
+*.ipdb
+*.ilk
+*.iobj
+*.obj
+*.opensdf
+*.pdb
+*.sdf
+*.suo
+*.tlog
+*.vcxproj.user
+*.vc.db
+*.vc.opendb
diff --git a/win32/VS2015/celt.vcxproj b/win32/VS2015/celt.vcxproj
deleted file mode 100644
index 273ee4d..0000000
--- a/win32/VS2015/celt.vcxproj
+++ /dev/null
@@ -1,593 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugDLL|Win32">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugDLL|x64">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|Win32">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|x64">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\celt\bands.c" />
-    <ClCompile Include="..\..\celt\celt.c" />
-    <ClCompile Include="..\..\celt\celt_decoder.c" />
-    <ClCompile Include="..\..\celt\celt_encoder.c" />
-    <ClCompile Include="..\..\celt\celt_lpc.c" />
-    <ClCompile Include="..\..\celt\cwrs.c" />
-    <ClCompile Include="..\..\celt\entcode.c" />
-    <ClCompile Include="..\..\celt\entdec.c" />
-    <ClCompile Include="..\..\celt\entenc.c" />
-    <ClCompile Include="..\..\celt\kiss_fft.c" />
-    <ClCompile Include="..\..\celt\laplace.c" />
-    <ClCompile Include="..\..\celt\mathops.c" />
-    <ClCompile Include="..\..\celt\mdct.c" />
-    <ClCompile Include="..\..\celt\modes.c" />
-    <ClCompile Include="..\..\celt\pitch.c" />
-    <ClCompile Include="..\..\celt\quant_bands.c" />
-    <ClCompile Include="..\..\celt\rate.c" />
-    <ClCompile Include="..\..\celt\vq.c" />
-    <ClCompile Include="..\..\celt\x86\celt_lpc_sse.c" />
-    <ClCompile Include="..\..\celt\x86\pitch_sse.c" />
-    <ClCompile Include="..\..\celt\x86\pitch_sse2.c" />
-    <ClCompile Include="..\..\celt\x86\pitch_sse4_1.c" />
-    <ClCompile Include="..\..\celt\x86\x86cpu.c" />
-    <ClCompile Include="..\..\celt\x86\x86_celt_map.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\celt\arch.h" />
-    <ClInclude Include="..\..\celt\bands.h" />
-    <ClInclude Include="..\..\celt\celt.h" />
-    <ClInclude Include="..\..\celt\celt_lpc.h" />
-    <ClInclude Include="..\..\celt\cwrs.h" />
-    <ClInclude Include="..\..\celt\ecintrin.h" />
-    <ClInclude Include="..\..\celt\entcode.h" />
-    <ClInclude Include="..\..\celt\entdec.h" />
-    <ClInclude Include="..\..\celt\entenc.h" />
-    <ClInclude Include="..\..\celt\fixed_c5x.h" />
-    <ClInclude Include="..\..\celt\fixed_c6x.h" />
-    <ClInclude Include="..\..\celt\fixed_debug.h" />
-    <ClInclude Include="..\..\celt\fixed_generic.h" />
-    <ClInclude Include="..\..\celt\float_cast.h" />
-    <ClInclude Include="..\..\celt\kiss_fft.h" />
-    <ClInclude Include="..\..\celt\laplace.h" />
-    <ClInclude Include="..\..\celt\mathops.h" />
-    <ClInclude Include="..\..\celt\mdct.h" />
-    <ClInclude Include="..\..\celt\mfrngcod.h" />
-    <ClInclude Include="..\..\celt\modes.h" />
-    <ClInclude Include="..\..\celt\os_support.h" />
-    <ClInclude Include="..\..\celt\pitch.h" />
-    <ClInclude Include="..\..\celt\quant_bands.h" />
-    <ClInclude Include="..\..\celt\rate.h" />
-    <ClInclude Include="..\..\celt\stack_alloc.h" />
-    <ClInclude Include="..\..\celt\static_modes_fixed.h" />
-    <ClInclude Include="..\..\celt\static_modes_float.h" />
-    <ClInclude Include="..\..\celt\vq.h" />
-    <ClInclude Include="..\..\celt\x86\celt_lpc_sse.h" />
-    <ClInclude Include="..\..\celt\x86\pitch_sse.h" />
-    <ClInclude Include="..\..\celt\x86\x86cpu.h" />
-    <ClInclude Include="..\..\celt\_kiss_fft_guts.h" />
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{245603E3-F580-41A5-9632-B25FE3372CBF}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>celt</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <CustomBuildBeforeTargets />
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\;..\..\include;..\..\celt;..\..\silk;..\..\silk\float;..\..\silk\fixed;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/celt.vcxproj.filters b/win32/VS2015/celt.vcxproj.filters
deleted file mode 100644
index e9948fa..0000000
--- a/win32/VS2015/celt.vcxproj.filters
+++ /dev/null
@@ -1,189 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\celt\celt_decoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\celt_encoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\celt_lpc.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\cwrs.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\entcode.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\entdec.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\entenc.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\kiss_fft.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\laplace.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\mathops.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\mdct.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\modes.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\pitch.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\quant_bands.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\rate.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\vq.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\bands.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\celt.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\x86\celt_lpc_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\x86\pitch_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\x86\pitch_sse2.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\x86\pitch_sse4_1.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\x86\x86_celt_map.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\celt\x86\x86cpu.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\celt\cwrs.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\ecintrin.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\entcode.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\entdec.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\entenc.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\fixed_c5x.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\fixed_c6x.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\fixed_debug.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\fixed_generic.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\float_cast.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\kiss_fft.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\laplace.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\mathops.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\mdct.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\mfrngcod.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\modes.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\os_support.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\pitch.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\quant_bands.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\rate.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\stack_alloc.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\static_modes_fixed.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\static_modes_float.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\vq.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\_kiss_fft_guts.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\arch.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\bands.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\celt.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\celt_lpc.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\x86\celt_lpc_sse.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\x86\pitch_sse.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\x86\x86cpu.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/common.props b/win32/VS2015/common.props
new file mode 100644
index 0000000..6c757d8
--- /dev/null
+++ b/win32/VS2015/common.props
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <OutDir>$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
+    <CharacterSet Condition="'$(ConfigurationType)'=='Application'">Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug' or '$(Configuration)'=='DebugDLL' or '$(Configuration)'=='DebugDLL_fixed'">
+    <LinkIncremental>true</LinkIncremental>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <WholeProgramOptimization>false</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release' or '$(Configuration)'=='ReleaseDLL' or '$(Configuration)'=='ReleaseDLL_fixed'">
+    <LinkIncremental>false</LinkIncremental>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <CompileAsManaged>false</CompileAsManaged>
+      <CompileAsWinRT>false</CompileAsWinRT>
+      <AdditionalIncludeDirectories>..\..;..\..\include;..\..\silk;..\..\celt;..\..\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <OpenMPSupport>false</OpenMPSupport>
+    </ClCompile>
+    <Lib>
+      <SubSystem>Console</SubSystem>
+    </Lib>
+    <Link>
+      <LargeAddressAware>true</LargeAddressAware>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug' or '$(Configuration)'=='DebugDLL' or '$(Configuration)'=='DebugDLL_fixed'">
+    <ClCompile>
+      <ControlFlowGuard>Guard</ControlFlowGuard>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <EnableEnhancedInstructionSet Condition="'$(Platform)'=='Win32'">NoExtensions</EnableEnhancedInstructionSet>
+      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
+      <FloatingPointExceptions>true</FloatingPointExceptions>
+      <FunctionLevelLinking>false</FunctionLevelLinking>
+      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
+      <MultiProcessorCompilation>false</MultiProcessorCompilation>
+      <OmitFramePointers>false</OmitFramePointers>
+      <Optimization>Disabled</Optimization>
+      <RuntimeLibrary Condition="'$(Configuration)'=='Debug'">MultiThreadedDebug</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(Configuration)'!='Debug'">MultiThreadedDebugDLL</RuntimeLibrary>
+      <SDLCheck>true</SDLCheck>
+      <StringPooling>false</StringPooling>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release' or '$(Configuration)'=='ReleaseDLL' or '$(Configuration)'=='ReleaseDLL_fixed'">
+    <ClCompile>
+      <ControlFlowGuard>false</ControlFlowGuard>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
+      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
+      <ExceptionHandling>false</ExceptionHandling>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+      <FloatingPointModel Condition="'$(Configuration)'=='Release'">Fast</FloatingPointModel>
+      <FloatingPointModel Condition="'$(Configuration)'!='Release'">Precise</FloatingPointModel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <Optimization>MaxSpeed</Optimization>
+      <RuntimeLibrary Condition="'$(Configuration)'=='Release'">MultiThreaded</RuntimeLibrary>
+      <RuntimeLibrary Condition="'$(Configuration)'!='Release'">MultiThreadedDLL</RuntimeLibrary>
+      <StructMemberAlignment>16Bytes</StructMemberAlignment>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup />
+</Project>
\ No newline at end of file
diff --git a/win32/VS2015/opus.sln b/win32/VS2015/opus.sln
index 24bead4..7b678e7 100644
--- a/win32/VS2015/opus.sln
+++ b/win32/VS2015/opus.sln
@@ -1,64 +1,42 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.25420.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "opus.vcxproj", "{219EC965-228A-1824-174D-96449D05F88A}"
-	ProjectSection(ProjectDependencies) = postProject
-		{8484C90D-1561-402F-A91D-2DB10F8C5171} = {8484C90D-1561-402F-A91D-2DB10F8C5171}
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}
-		{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "celt", "celt.vcxproj", "{245603E3-F580-41A5-9632-B25FE3372CBF}"
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus_demo", "opus_demo.vcxproj", "{016C739D-6389-43BF-8D88-24B2BF6F620F}"
 	ProjectSection(ProjectDependencies) = postProject
 		{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}
-		{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_opus_api", "test_opus_api.vcxproj", "{1D257A17-D254-42E5-82D6-1C87A6EC775A}"
 	ProjectSection(ProjectDependencies) = postProject
 		{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}
-		{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_opus_decode", "test_opus_decode.vcxproj", "{8578322A-1883-486B-B6FA-E0094B65C9F2}"
 	ProjectSection(ProjectDependencies) = postProject
 		{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}
-		{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_opus_encode", "test_opus_encode.vcxproj", "{84DAA768-1A38-4312-BB61-4C78BB59E5B8}"
 	ProjectSection(ProjectDependencies) = postProject
 		{219EC965-228A-1824-174D-96449D05F88A} = {219EC965-228A-1824-174D-96449D05F88A}
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782} = {9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}
-		{245603E3-F580-41A5-9632-B25FE3372CBF} = {245603E3-F580-41A5-9632-B25FE3372CBF}
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16} = {C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "silk_float", "silk_float.vcxproj", "{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "silk_common", "silk_common.vcxproj", "{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "silk_fixed", "silk_fixed.vcxproj", "{8484C90D-1561-402F-A91D-2DB10F8C5171}"
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
 		Debug|x64 = Debug|x64
+		DebugDLL_fixed|Win32 = DebugDLL_fixed|Win32
+		DebugDLL_fixed|x64 = DebugDLL_fixed|x64
 		DebugDLL|Win32 = DebugDLL|Win32
 		DebugDLL|x64 = DebugDLL|x64
 		Release|Win32 = Release|Win32
 		Release|x64 = Release|x64
+		ReleaseDLL_fixed|Win32 = ReleaseDLL_fixed|Win32
+		ReleaseDLL_fixed|x64 = ReleaseDLL_fixed|x64
 		ReleaseDLL|Win32 = ReleaseDLL|Win32
 		ReleaseDLL|x64 = ReleaseDLL|x64
 	EndGlobalSection
@@ -67,6 +45,10 @@
 		{219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.Build.0 = Debug|Win32
 		{219EC965-228A-1824-174D-96449D05F88A}.Debug|x64.ActiveCfg = Debug|x64
 		{219EC965-228A-1824-174D-96449D05F88A}.Debug|x64.Build.0 = Debug|x64
+		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32
+		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32
+		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64
+		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64
 		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
 		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
@@ -75,30 +57,22 @@
 		{219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.Build.0 = Release|Win32
 		{219EC965-228A-1824-174D-96449D05F88A}.Release|x64.ActiveCfg = Release|x64
 		{219EC965-228A-1824-174D-96449D05F88A}.Release|x64.Build.0 = Release|x64
+		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32
+		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32
+		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64
+		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64
 		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
 		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
 		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{219EC965-228A-1824-174D-96449D05F88A}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.ActiveCfg = Debug|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|Win32.Build.0 = Debug|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.ActiveCfg = Debug|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Debug|x64.Build.0 = Debug|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.ActiveCfg = Release|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|Win32.Build.0 = Release|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.ActiveCfg = Release|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.Release|x64.Build.0 = Release|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{245603E3-F580-41A5-9632-B25FE3372CBF}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|Win32.Build.0 = Debug|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|x64.ActiveCfg = Debug|x64
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Debug|x64.Build.0 = Debug|x64
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
@@ -107,6 +81,10 @@
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.Build.0 = Release|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|x64.ActiveCfg = Release|x64
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|x64.Build.0 = Release|x64
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64
+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
 		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
@@ -115,6 +93,10 @@
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.Build.0 = Debug|Win32
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|x64.ActiveCfg = Debug|x64
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|x64.Build.0 = Debug|x64
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
@@ -123,6 +105,10 @@
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.Build.0 = Release|Win32
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|x64.ActiveCfg = Release|x64
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|x64.Build.0 = Release|x64
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64
+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
 		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
@@ -131,6 +117,10 @@
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.Build.0 = Debug|Win32
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|x64.ActiveCfg = Debug|x64
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|x64.Build.0 = Debug|x64
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
@@ -139,6 +129,10 @@
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.Build.0 = Release|Win32
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|x64.ActiveCfg = Release|x64
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|x64.Build.0 = Release|x64
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64
+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
 		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
@@ -147,6 +141,10 @@
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.Build.0 = Debug|Win32
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|x64.ActiveCfg = Debug|x64
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|x64.Build.0 = Debug|x64
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|Win32.ActiveCfg = DebugDLL_fixed|Win32
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|Win32.Build.0 = DebugDLL_fixed|Win32
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|x64.ActiveCfg = DebugDLL_fixed|x64
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL_fixed|x64.Build.0 = DebugDLL_fixed|x64
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
@@ -155,58 +153,14 @@
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.Build.0 = Release|Win32
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|x64.ActiveCfg = Release|x64
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|x64.Build.0 = Release|x64
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|Win32.ActiveCfg = ReleaseDLL_fixed|Win32
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|Win32.Build.0 = ReleaseDLL_fixed|Win32
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|x64.ActiveCfg = ReleaseDLL_fixed|x64
+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL_fixed|x64.Build.0 = ReleaseDLL_fixed|x64
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
 		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|Win32.Build.0 = Debug|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.ActiveCfg = Debug|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Debug|x64.Build.0 = Debug|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.ActiveCfg = Release|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|Win32.Build.0 = Release|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.ActiveCfg = Release|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.Release|x64.Build.0 = Release|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|Win32.Build.0 = Debug|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.ActiveCfg = Debug|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Debug|x64.Build.0 = Debug|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.ActiveCfg = Release|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|Win32.Build.0 = Release|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.ActiveCfg = Release|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.Release|x64.Build.0 = Release|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.ActiveCfg = Debug|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|Win32.Build.0 = Debug|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.ActiveCfg = Debug|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Debug|x64.Build.0 = Debug|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.DebugDLL|Win32.Build.0 = DebugDLL|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.DebugDLL|x64.ActiveCfg = DebugDLL|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.ActiveCfg = Release|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|Win32.Build.0 = Release|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.ActiveCfg = Release|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.Release|x64.Build.0 = Release|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64
-		{8484C90D-1561-402F-A91D-2DB10F8C5171}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/win32/VS2015/opus.vcxproj b/win32/VS2015/opus.vcxproj
index 0559aa6..33bf706 100644
--- a/win32/VS2015/opus.vcxproj
+++ b/win32/VS2015/opus.vcxproj
@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL_fixed|Win32">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL_fixed|x64">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugDLL|Win32">
       <Configuration>DebugDLL</Configuration>
       <Platform>Win32</Platform>
@@ -17,6 +25,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|Win32">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|x64">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="ReleaseDLL|Win32">
       <Configuration>ReleaseDLL</Configuration>
       <Platform>Win32</Platform>
@@ -38,534 +54,184 @@
     <Keyword>Win32Proj</Keyword>
     <ProjectName>opus</ProjectName>
     <ProjectGuid>{219EC965-228A-1824-174D-96449D05F88A}</ProjectGuid>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <UseDebugLibraries>false</UseDebugLibraries>
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <UseDebugLibraries>false</UseDebugLibraries>
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
     <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
     <PlatformToolset>v140</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <CustomBuildBeforeTargets />
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+  <ItemDefinitionGroup>
     <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <Optimization>Disabled</Optimization>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
+      <AdditionalIncludeDirectories>..\..\silk\fixed;..\..\silk\float;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(ConfigurationType)'=='DynamicLibrary'">DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions Condition="'$(Configuration)'=='DebugDLL_fixed' or '$(Configuration)'=='ReleaseDLL_fixed'">FIXED_POINT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalOptions Condition="'$(Platform)'=='Win32'">/arch:IA32 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
-    <Link>
-      <TargetMachine>MachineX86</TargetMachine>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
     <Lib>
-      <SubSystem>Windows</SubSystem>
+      <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>
     </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <Optimization>Disabled</Optimization>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-    </ClCompile>
-    <Link>
-      <TargetMachine>MachineX86</TargetMachine>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <EnableCOMDATFolding>false</EnableCOMDATFolding>
-    </Link>
     <PreBuildEvent>
       <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
       <Message>Generating version.h</Message>
     </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <Lib>
-      <SubSystem>Windows</SubSystem>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <Optimization>Disabled</Optimization>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <Lib>
-      <SubSystem>Windows</SubSystem>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_CONSOLE;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <Optimization>Disabled</Optimization>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <EnableCOMDATFolding>false</EnableCOMDATFolding>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-    <Lib>
-      <SubSystem>Windows</SubSystem>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <TargetMachine>MachineX86</TargetMachine>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <LinkStatus>false</LinkStatus>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <TargetMachine>MachineX86</TargetMachine>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <LinkStatus>true</LinkStatus>
-      <LargeAddressAware>true</LargeAddressAware>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Configuration)$(PlatformArchitecture);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <LinkStatus>false</LinkStatus>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_CONSOLE;DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk;../../celt;../../win32;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <WarningLevel>Level3</WarningLevel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>celt.lib;silk_common.lib;silk_fixed.lib;silk_float.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
-      <LinkStatus>true</LinkStatus>
-      <LargeAddressAware>true</LargeAddressAware>
-    </Link>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="..\..\celt\arch.h" />
+    <ClInclude Include="..\..\celt\bands.h" />
     <ClInclude Include="..\..\celt\celt.h" />
+    <ClInclude Include="..\..\celt\celt_lpc.h" />
+    <ClInclude Include="..\..\celt\cwrs.h" />
+    <ClInclude Include="..\..\celt\ecintrin.h" />
+    <ClInclude Include="..\..\celt\entcode.h" />
     <ClInclude Include="..\..\celt\entdec.h" />
     <ClInclude Include="..\..\celt\entenc.h" />
+    <ClInclude Include="..\..\celt\fixed_c5x.h" />
+    <ClInclude Include="..\..\celt\fixed_c6x.h" />
+    <ClInclude Include="..\..\celt\fixed_debug.h" />
+    <ClInclude Include="..\..\celt\fixed_generic.h" />
     <ClInclude Include="..\..\celt\float_cast.h" />
+    <ClInclude Include="..\..\celt\kiss_fft.h" />
+    <ClInclude Include="..\..\celt\laplace.h" />
+    <ClInclude Include="..\..\celt\mathops.h" />
+    <ClInclude Include="..\..\celt\mdct.h" />
+    <ClInclude Include="..\..\celt\mfrngcod.h" />
+    <ClInclude Include="..\..\celt\modes.h" />
     <ClInclude Include="..\..\celt\os_support.h" />
+    <ClInclude Include="..\..\celt\pitch.h" />
+    <ClInclude Include="..\..\celt\quant_bands.h" />
+    <ClInclude Include="..\..\celt\rate.h" />
     <ClInclude Include="..\..\celt\stack_alloc.h" />
+    <ClInclude Include="..\..\celt\static_modes_fixed.h" />
+    <ClInclude Include="..\..\celt\static_modes_float.h" />
+    <ClInclude Include="..\..\celt\vq.h" />
+    <ClInclude Include="..\..\celt\x86\celt_lpc_sse.h" />
+    <ClInclude Include="..\..\celt\x86\pitch_sse.h" />
+    <ClInclude Include="..\..\celt\x86\vq_sse.h" />
+    <ClInclude Include="..\..\celt\x86\x86cpu.h" />
+    <ClInclude Include="..\..\celt\_kiss_fft_guts.h" />
     <ClInclude Include="..\..\include\opus.h" />
     <ClInclude Include="..\..\include\opus_defines.h" />
     <ClInclude Include="..\..\include\opus_types.h" />
     <ClInclude Include="..\..\include\opus_multistream.h" />
+    <ClInclude Include="..\..\silk\API.h" />
+    <ClInclude Include="..\..\silk\control.h" />
+    <ClInclude Include="..\..\silk\debug.h" />
+    <ClInclude Include="..\..\silk\define.h" />
+    <ClInclude Include="..\..\silk\errors.h" />
+    <ClInclude Include="..\..\silk\float\main_FLP.h" />
+    <ClInclude Include="..\..\silk\float\SigProc_FLP.h" />
+    <ClInclude Include="..\..\silk\float\structs_FLP.h" />
+    <ClInclude Include="..\..\silk\Inlines.h" />
+    <ClInclude Include="..\..\silk\MacroCount.h" />
+    <ClInclude Include="..\..\silk\MacroDebug.h" />
+    <ClInclude Include="..\..\silk\macros.h" />
+    <ClInclude Include="..\..\silk\main.h" />
+    <ClInclude Include="..\..\silk\pitch_est_defines.h" />
+    <ClInclude Include="..\..\silk\PLC.h" />
+    <ClInclude Include="..\..\silk\resampler_private.h" />
+    <ClInclude Include="..\..\silk\resampler_rom.h" />
+    <ClInclude Include="..\..\silk\resampler_structs.h" />
+    <ClInclude Include="..\..\silk\structs.h" />
+    <ClInclude Include="..\..\silk\tables.h" />
+    <ClInclude Include="..\..\silk\tuning_parameters.h" />
+    <ClInclude Include="..\..\silk\typedef.h" />
+    <ClInclude Include="..\..\silk\x86\main_sse.h" />
     <ClInclude Include="..\..\win32\config.h" />
     <ClInclude Include="..\..\src\analysis.h" />
     <ClInclude Include="..\..\src\mlp.h" />
@@ -573,11 +239,120 @@
     <ClInclude Include="..\..\src\tansig_table.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\..\celt\bands.c" />
+    <ClCompile Include="..\..\celt\celt.c" />
+    <ClCompile Include="..\..\celt\celt_decoder.c" />
+    <ClCompile Include="..\..\celt\celt_encoder.c" />
+    <ClCompile Include="..\..\celt\celt_lpc.c" />
+    <ClCompile Include="..\..\celt\cwrs.c" />
+    <ClCompile Include="..\..\celt\entcode.c" />
+    <ClCompile Include="..\..\celt\entdec.c" />
+    <ClCompile Include="..\..\celt\entenc.c" />
+    <ClCompile Include="..\..\celt\kiss_fft.c" />
+    <ClCompile Include="..\..\celt\laplace.c" />
+    <ClCompile Include="..\..\celt\mathops.c" />
+    <ClCompile Include="..\..\celt\mdct.c" />
+    <ClCompile Include="..\..\celt\modes.c" />
+    <ClCompile Include="..\..\celt\pitch.c" />
+    <ClCompile Include="..\..\celt\quant_bands.c" />
+    <ClCompile Include="..\..\celt\rate.c" />
+    <ClCompile Include="..\..\celt\vq.c" />
+    <ClCompile Include="..\..\celt\x86\celt_lpc_sse.c" />
+    <ClCompile Include="..\..\celt\x86\pitch_sse.c" />
+    <ClCompile Include="..\..\celt\x86\pitch_sse2.c" />
+    <ClCompile Include="..\..\celt\x86\pitch_sse4_1.c" />
+    <ClCompile Include="..\..\celt\x86\vq_sse2.c" />
+    <ClCompile Include="..\..\celt\x86\x86cpu.c" />
+    <ClCompile Include="..\..\celt\x86\x86_celt_map.c" />
+    <ClCompile Include="..\..\silk\A2NLSF.c" />
+    <ClCompile Include="..\..\silk\ana_filt_bank_1.c" />
+    <ClCompile Include="..\..\silk\biquad_alt.c" />
+    <ClCompile Include="..\..\silk\bwexpander.c" />
+    <ClCompile Include="..\..\silk\bwexpander_32.c" />
+    <ClCompile Include="..\..\silk\check_control_input.c" />
+    <ClCompile Include="..\..\silk\CNG.c" />
+    <ClCompile Include="..\..\silk\code_signs.c" />
+    <ClCompile Include="..\..\silk\control_audio_bandwidth.c" />
+    <ClCompile Include="..\..\silk\control_codec.c" />
+    <ClCompile Include="..\..\silk\control_SNR.c" />
+    <ClCompile Include="..\..\silk\debug.c" />
+    <ClCompile Include="..\..\silk\decoder_set_fs.c" />
+    <ClCompile Include="..\..\silk\decode_core.c" />
+    <ClCompile Include="..\..\silk\decode_frame.c" />
+    <ClCompile Include="..\..\silk\decode_indices.c" />
+    <ClCompile Include="..\..\silk\decode_parameters.c" />
+    <ClCompile Include="..\..\silk\decode_pitch.c" />
+    <ClCompile Include="..\..\silk\decode_pulses.c" />
+    <ClCompile Include="..\..\silk\dec_API.c" />
+    <ClCompile Include="..\..\silk\encode_indices.c" />
+    <ClCompile Include="..\..\silk\encode_pulses.c" />
+    <ClCompile Include="..\..\silk\enc_API.c" />
+    <ClCompile Include="..\..\silk\gain_quant.c" />
+    <ClCompile Include="..\..\silk\HP_variable_cutoff.c" />
+    <ClCompile Include="..\..\silk\init_decoder.c" />
+    <ClCompile Include="..\..\silk\init_encoder.c" />
+    <ClCompile Include="..\..\silk\inner_prod_aligned.c" />
+    <ClCompile Include="..\..\silk\interpolate.c" />
+    <ClCompile Include="..\..\silk\lin2log.c" />
+    <ClCompile Include="..\..\silk\log2lin.c" />
+    <ClCompile Include="..\..\silk\LPC_analysis_filter.c" />
+    <ClCompile Include="..\..\silk\LPC_fit.c" />
+    <ClCompile Include="..\..\silk\LPC_inv_pred_gain.c" />
+    <ClCompile Include="..\..\silk\LP_variable_cutoff.c" />
+    <ClCompile Include="..\..\silk\NLSF2A.c" />
+    <ClCompile Include="..\..\silk\NLSF_decode.c" />
+    <ClCompile Include="..\..\silk\NLSF_del_dec_quant.c" />
+    <ClCompile Include="..\..\silk\NLSF_encode.c" />
+    <ClCompile Include="..\..\silk\NLSF_stabilize.c" />
+    <ClCompile Include="..\..\silk\NLSF_unpack.c" />
+    <ClCompile Include="..\..\silk\NLSF_VQ.c" />
+    <ClCompile Include="..\..\silk\NLSF_VQ_weights_laroia.c" />
+    <ClCompile Include="..\..\silk\NSQ.c" />
+    <ClCompile Include="..\..\silk\NSQ_del_dec.c" />
+    <ClCompile Include="..\..\silk\pitch_est_tables.c" />
+    <ClCompile Include="..\..\silk\PLC.c" />
+    <ClCompile Include="..\..\silk\process_NLSFs.c" />
+    <ClCompile Include="..\..\silk\quant_LTP_gains.c" />
+    <ClCompile Include="..\..\silk\resampler.c" />
+    <ClCompile Include="..\..\silk\resampler_down2.c" />
+    <ClCompile Include="..\..\silk\resampler_down2_3.c" />
+    <ClCompile Include="..\..\silk\resampler_private_AR2.c" />
+    <ClCompile Include="..\..\silk\resampler_private_down_FIR.c" />
+    <ClCompile Include="..\..\silk\resampler_private_IIR_FIR.c" />
+    <ClCompile Include="..\..\silk\resampler_private_up2_HQ.c" />
+    <ClCompile Include="..\..\silk\resampler_rom.c" />
+    <ClCompile Include="..\..\silk\shell_coder.c" />
+    <ClCompile Include="..\..\silk\sigm_Q15.c" />
+    <ClCompile Include="..\..\silk\sort.c" />
+    <ClCompile Include="..\..\silk\stereo_decode_pred.c" />
+    <ClCompile Include="..\..\silk\stereo_encode_pred.c" />
+    <ClCompile Include="..\..\silk\stereo_find_predictor.c" />
+    <ClCompile Include="..\..\silk\stereo_LR_to_MS.c" />
+    <ClCompile Include="..\..\silk\stereo_MS_to_LR.c" />
+    <ClCompile Include="..\..\silk\stereo_quant_pred.c" />
+    <ClCompile Include="..\..\silk\sum_sqr_shift.c" />
+    <ClCompile Include="..\..\silk\tables_gain.c" />
+    <ClCompile Include="..\..\silk\tables_LTP.c" />
+    <ClCompile Include="..\..\silk\tables_NLSF_CB_NB_MB.c" />
+    <ClCompile Include="..\..\silk\tables_NLSF_CB_WB.c" />
+    <ClCompile Include="..\..\silk\tables_other.c" />
+    <ClCompile Include="..\..\silk\tables_pitch_lag.c" />
+    <ClCompile Include="..\..\silk\tables_pulses_per_block.c" />
+    <ClCompile Include="..\..\silk\table_LSF_cos.c" />
+    <ClCompile Include="..\..\silk\VAD.c" />
+    <ClCompile Include="..\..\silk\VQ_WMat_EC.c" />
+    <ClCompile Include="..\..\silk\x86\NSQ_del_dec_sse.c" />
+    <ClCompile Include="..\..\silk\x86\NSQ_sse.c" />
+    <ClCompile Include="..\..\silk\x86\VAD_sse.c" />
+    <ClCompile Include="..\..\silk\x86\VQ_WMat_EC_sse.c" />
+    <ClCompile Include="..\..\silk\x86\x86_silk_map.c" />
     <ClCompile Include="..\..\src\analysis.c" />
     <ClCompile Include="..\..\src\mlp.c" />
     <ClCompile Include="..\..\src\mlp_data.c" />
     <ClCompile Include="..\..\src\opus.c" />
-    <ClCompile Include="..\..\src\opus_compare.c" />
+    <ClCompile Include="..\..\src\opus_compare.c">
+      <DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+    </ClCompile>
     <ClCompile Include="..\..\src\opus_decoder.c" />
     <ClCompile Include="..\..\src\opus_encoder.c" />
     <ClCompile Include="..\..\src\opus_multistream.c" />
@@ -585,6 +360,34 @@
     <ClCompile Include="..\..\src\opus_multistream_encoder.c" />
     <ClCompile Include="..\..\src\repacketizer.c" />
   </ItemGroup>
+  <Choose>
+    <When Condition="'$(Configuration)'=='DebugDLL_fixed' or '$(Configuration)'=='ReleaseDLL_fixed' or $(PreprocessorDefinitions.Contains('FIXED_POINT'))">
+      <ItemGroup>
+        <ClCompile Include="..\..\silk\fixed\*.c">
+          <ExcludedFromBuild>false</ExcludedFromBuild>
+        </ClCompile>
+        <ClCompile Include="..\..\silk\fixed\x86\*.c">
+          <ExcludedFromBuild>false</ExcludedFromBuild>
+        </ClCompile>
+        <ClCompile Include="..\..\silk\float\*.c">
+          <ExcludedFromBuild>true</ExcludedFromBuild>
+        </ClCompile>
+      </ItemGroup>
+    </When>
+    <Otherwise>
+      <ItemGroup>
+        <ClCompile Include="..\..\silk\fixed\*.c">
+          <ExcludedFromBuild>true</ExcludedFromBuild>
+        </ClCompile>
+        <ClCompile Include="..\..\silk\fixed\x86\*.c">
+          <ExcludedFromBuild>true</ExcludedFromBuild>
+        </ClCompile>
+        <ClCompile Include="..\..\silk\float\*.c">
+          <ExcludedFromBuild>false</ExcludedFromBuild>
+        </ClCompile>
+      </ItemGroup>
+    </Otherwise>
+  </Choose>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/win32/VS2015/opus.vcxproj.filters b/win32/VS2015/opus.vcxproj.filters
index 7160778..bb82b64 100644
--- a/win32/VS2015/opus.vcxproj.filters
+++ b/win32/VS2015/opus.vcxproj.filters
@@ -63,8 +63,209 @@
     <ClInclude Include="..\..\src\tansig_table.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\celt\x86\x86cpu.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\_kiss_fft_guts.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\bands.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\celt_lpc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\x86\celt_lpc_sse.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\cwrs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\ecintrin.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\entcode.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\fixed_c5x.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\fixed_c6x.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\fixed_debug.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\fixed_generic.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\kiss_fft.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\laplace.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\mathops.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\mdct.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\mfrngcod.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\modes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\pitch.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\x86\pitch_sse.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\quant_bands.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\rate.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\static_modes_fixed.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\static_modes_float.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\vq.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\typedef.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\API.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\control.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\debug.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\define.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\errors.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\Inlines.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\MacroCount.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\MacroDebug.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\macros.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\main.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\x86\main_sse.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\pitch_est_defines.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\PLC.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\resampler_private.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\resampler_rom.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\resampler_structs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\structs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\tables.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\tuning_parameters.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\float\main_FLP.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\float\SigProc_FLP.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\silk\float\structs_FLP.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\celt\x86\vq_sse.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\..\src\analysis.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\bands.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\celt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\celt_decoder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\celt_encoder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\celt_lpc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\x86\celt_lpc_sse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\cwrs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\entcode.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\entdec.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\entenc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\kiss_fft.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\laplace.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\mathops.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\mdct.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\mlp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\mlp_data.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\modes.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\opus.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -86,17 +287,284 @@
     <ClCompile Include="..\..\src\opus_multistream_encoder.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\celt\pitch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\x86\pitch_sse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\x86\pitch_sse2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\x86\pitch_sse4_1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\quant_bands.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\rate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\repacketizer.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\analysis.c">
+    <ClCompile Include="..\..\celt\vq.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\mlp.c">
+    <ClCompile Include="..\..\celt\x86\x86_celt_map.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\mlp_data.c">
+    <ClCompile Include="..\..\celt\x86\x86cpu.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\A2NLSF.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\ana_filt_bank_1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\biquad_alt.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\bwexpander.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\bwexpander_32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\check_control_input.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\CNG.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\code_signs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\control_audio_bandwidth.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\control_codec.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\control_SNR.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\debug.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\dec_API.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decode_core.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decode_frame.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decode_indices.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decode_parameters.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decode_pitch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decode_pulses.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\decoder_set_fs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\enc_API.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\encode_indices.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\encode_pulses.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\gain_quant.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\HP_variable_cutoff.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\init_decoder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\init_encoder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\inner_prod_aligned.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\interpolate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\lin2log.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\log2lin.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\LP_variable_cutoff.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\LPC_analysis_filter.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\LPC_inv_pred_gain.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_decode.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_del_dec_quant.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_encode.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_stabilize.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_unpack.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_VQ.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF_VQ_weights_laroia.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NLSF2A.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NSQ.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\NSQ_del_dec.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\x86\NSQ_del_dec_sse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\x86\NSQ_sse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\pitch_est_tables.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\PLC.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\process_NLSFs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\quant_LTP_gains.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_down2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_down2_3.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_private_AR2.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_private_down_FIR.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_private_IIR_FIR.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_private_up2_HQ.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\resampler_rom.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\shell_coder.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\sigm_Q15.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\sort.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\stereo_decode_pred.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\stereo_encode_pred.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\stereo_find_predictor.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\stereo_LR_to_MS.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\stereo_MS_to_LR.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\stereo_quant_pred.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\sum_sqr_shift.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\table_LSF_cos.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_gain.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_LTP.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_NLSF_CB_NB_MB.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_NLSF_CB_WB.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_other.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_pitch_lag.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\tables_pulses_per_block.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\VAD.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\x86\VAD_sse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\VQ_WMat_EC.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\x86\VQ_WMat_EC_sse.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\x86\x86_silk_map.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\silk\LPC_fit.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\celt\x86\vq_sse2.c">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/win32/VS2015/opus_demo.vcxproj b/win32/VS2015/opus_demo.vcxproj
index 275241f..f4344e5 100644
--- a/win32/VS2015/opus_demo.vcxproj
+++ b/win32/VS2015/opus_demo.vcxproj
@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL_fixed|Win32">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL_fixed|x64">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugDLL|Win32">
       <Configuration>DebugDLL</Configuration>
       <Platform>Win32</Platform>
@@ -17,6 +25,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|Win32">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|x64">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="ReleaseDLL|Win32">
       <Configuration>ReleaseDLL</Configuration>
       <Platform>Win32</Platform>
@@ -35,18 +51,9 @@
     </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="celt.vcxproj">
-      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>
-    </ProjectReference>
     <ProjectReference Include="opus.vcxproj">
       <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
     </ProjectReference>
-    <ProjectReference Include="silk_common.vcxproj">
-      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>
-    </ProjectReference>
-    <ProjectReference Include="silk_float.vcxproj">
-      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>
-    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\opus_demo.c" />
@@ -55,59 +62,54 @@
     <ProjectGuid>{016C739D-6389-43BF-8D88-24B2BF6F620F}</ProjectGuid>
     <Keyword>Win32Proj</Keyword>
     <RootNamespace>opus_demo</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -115,331 +117,54 @@
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
+  <ItemDefinitionGroup />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/win32/VS2015/silk_common.vcxproj b/win32/VS2015/silk_common.vcxproj
deleted file mode 100644
index 2df939b..0000000
--- a/win32/VS2015/silk_common.vcxproj
+++ /dev/null
@@ -1,664 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugDLL|Win32">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugDLL|x64">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|Win32">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|x64">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{C303D2FC-FF97-49B8-9DDD-467B4C9A0B16}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>src_common</RootNamespace>
-    <ProjectName>silk_common</ProjectName>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <CustomBuildBeforeTargets>
-    </CustomBuildBeforeTargets>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <CustomBuildBeforeTargets />
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk/float;../../silk;../../win32;../../celt;../../include</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\include\opus_types.h" />
-    <ClInclude Include="..\..\silk\x86\main_sse.h" />
-    <ClInclude Include="..\..\silk\x86\SigProc_FIX_sse.h" />
-    <ClInclude Include="..\..\win32\config.h" />
-    <ClInclude Include="..\..\silk\control.h" />
-    <ClInclude Include="..\..\silk\debug.h" />
-    <ClInclude Include="..\..\silk\define.h" />
-    <ClInclude Include="..\..\silk\errors.h" />
-    <ClInclude Include="..\..\silk\Inlines.h" />
-    <ClInclude Include="..\..\silk\MacroCount.h" />
-    <ClInclude Include="..\..\silk\MacroDebug.h" />
-    <ClInclude Include="..\..\silk\macros.h" />
-    <ClInclude Include="..\..\silk\main.h" />
-    <ClInclude Include="..\..\silk\pitch_est_defines.h" />
-    <ClInclude Include="..\..\silk\PLC.h" />
-    <ClInclude Include="..\..\silk\resampler_private.h" />
-    <ClInclude Include="..\..\silk\resampler_rom.h" />
-    <ClInclude Include="..\..\silk\resampler_structs.h" />
-    <ClInclude Include="..\..\silk\API.h" />
-    <ClInclude Include="..\..\silk\SigProc_FIX.h" />
-    <ClInclude Include="..\..\silk\structs.h" />
-    <ClInclude Include="..\..\silk\tables.h" />
-    <ClInclude Include="..\..\silk\tuning_parameters.h" />
-    <ClInclude Include="..\..\silk\typedef.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\silk\A2NLSF.c" />
-    <ClCompile Include="..\..\silk\ana_filt_bank_1.c" />
-    <ClCompile Include="..\..\silk\biquad_alt.c" />
-    <ClCompile Include="..\..\silk\bwexpander.c" />
-    <ClCompile Include="..\..\silk\bwexpander_32.c" />
-    <ClCompile Include="..\..\silk\check_control_input.c" />
-    <ClCompile Include="..\..\silk\CNG.c" />
-    <ClCompile Include="..\..\silk\code_signs.c" />
-    <ClCompile Include="..\..\silk\control_audio_bandwidth.c" />
-    <ClCompile Include="..\..\silk\control_codec.c" />
-    <ClCompile Include="..\..\silk\control_SNR.c" />
-    <ClCompile Include="..\..\silk\debug.c" />
-    <ClCompile Include="..\..\silk\decoder_set_fs.c" />
-    <ClCompile Include="..\..\silk\decode_core.c" />
-    <ClCompile Include="..\..\silk\decode_frame.c" />
-    <ClCompile Include="..\..\silk\decode_indices.c" />
-    <ClCompile Include="..\..\silk\decode_parameters.c" />
-    <ClCompile Include="..\..\silk\decode_pitch.c" />
-    <ClCompile Include="..\..\silk\decode_pulses.c" />
-    <ClCompile Include="..\..\silk\dec_API.c" />
-    <ClCompile Include="..\..\silk\encode_indices.c" />
-    <ClCompile Include="..\..\silk\encode_pulses.c" />
-    <ClCompile Include="..\..\silk\enc_API.c" />
-    <ClCompile Include="..\..\silk\gain_quant.c" />
-    <ClCompile Include="..\..\silk\HP_variable_cutoff.c" />
-    <ClCompile Include="..\..\silk\init_decoder.c" />
-    <ClCompile Include="..\..\silk\init_encoder.c" />
-    <ClCompile Include="..\..\silk\inner_prod_aligned.c" />
-    <ClCompile Include="..\..\silk\interpolate.c" />
-    <ClCompile Include="..\..\silk\lin2log.c" />
-    <ClCompile Include="..\..\silk\log2lin.c" />
-    <ClCompile Include="..\..\silk\LPC_analysis_filter.c" />
-    <ClCompile Include="..\..\silk\LPC_inv_pred_gain.c" />
-    <ClCompile Include="..\..\silk\LP_variable_cutoff.c" />
-    <ClCompile Include="..\..\silk\NLSF2A.c" />
-    <ClCompile Include="..\..\silk\NLSF_decode.c" />
-    <ClCompile Include="..\..\silk\NLSF_del_dec_quant.c" />
-    <ClCompile Include="..\..\silk\NLSF_encode.c" />
-    <ClCompile Include="..\..\silk\NLSF_stabilize.c" />
-    <ClCompile Include="..\..\silk\NLSF_unpack.c" />
-    <ClCompile Include="..\..\silk\NLSF_VQ.c" />
-    <ClCompile Include="..\..\silk\NLSF_VQ_weights_laroia.c" />
-    <ClCompile Include="..\..\silk\NSQ.c" />
-    <ClCompile Include="..\..\silk\NSQ_del_dec.c" />
-    <ClCompile Include="..\..\silk\pitch_est_tables.c" />
-    <ClCompile Include="..\..\silk\PLC.c" />
-    <ClCompile Include="..\..\silk\process_NLSFs.c" />
-    <ClCompile Include="..\..\silk\quant_LTP_gains.c" />
-    <ClCompile Include="..\..\silk\resampler.c" />
-    <ClCompile Include="..\..\silk\resampler_down2.c" />
-    <ClCompile Include="..\..\silk\resampler_down2_3.c" />
-    <ClCompile Include="..\..\silk\resampler_private_AR2.c" />
-    <ClCompile Include="..\..\silk\resampler_private_down_FIR.c" />
-    <ClCompile Include="..\..\silk\resampler_private_IIR_FIR.c" />
-    <ClCompile Include="..\..\silk\resampler_private_up2_HQ.c" />
-    <ClCompile Include="..\..\silk\resampler_rom.c" />
-    <ClCompile Include="..\..\silk\shell_coder.c" />
-    <ClCompile Include="..\..\silk\sigm_Q15.c" />
-    <ClCompile Include="..\..\silk\sort.c" />
-    <ClCompile Include="..\..\silk\stereo_decode_pred.c" />
-    <ClCompile Include="..\..\silk\stereo_encode_pred.c" />
-    <ClCompile Include="..\..\silk\stereo_find_predictor.c" />
-    <ClCompile Include="..\..\silk\stereo_LR_to_MS.c" />
-    <ClCompile Include="..\..\silk\stereo_MS_to_LR.c" />
-    <ClCompile Include="..\..\silk\stereo_quant_pred.c" />
-    <ClCompile Include="..\..\silk\sum_sqr_shift.c" />
-    <ClCompile Include="..\..\silk\tables_gain.c" />
-    <ClCompile Include="..\..\silk\tables_LTP.c" />
-    <ClCompile Include="..\..\silk\tables_NLSF_CB_NB_MB.c" />
-    <ClCompile Include="..\..\silk\tables_NLSF_CB_WB.c" />
-    <ClCompile Include="..\..\silk\tables_other.c" />
-    <ClCompile Include="..\..\silk\tables_pitch_lag.c" />
-    <ClCompile Include="..\..\silk\tables_pulses_per_block.c" />
-    <ClCompile Include="..\..\silk\table_LSF_cos.c" />
-    <ClCompile Include="..\..\silk\VAD.c" />
-    <ClCompile Include="..\..\silk\VQ_WMat_EC.c" />
-    <ClCompile Include="..\..\silk\x86\NSQ_del_dec_sse.c" />
-    <ClCompile Include="..\..\silk\x86\NSQ_sse.c" />
-    <ClCompile Include="..\..\silk\x86\VAD_sse.c" />
-    <ClCompile Include="..\..\silk\x86\VQ_WMat_EC_sse.c" />
-    <ClCompile Include="..\..\silk\x86\x86_silk_map.c" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/silk_common.vcxproj.filters b/win32/VS2015/silk_common.vcxproj.filters
deleted file mode 100644
index c41064e..0000000
--- a/win32/VS2015/silk_common.vcxproj.filters
+++ /dev/null
@@ -1,336 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\include\opus_types.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\win32\config.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\control.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\debug.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\define.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\errors.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\Inlines.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\MacroCount.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\MacroDebug.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\macros.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\main.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\pitch_est_defines.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\PLC.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\resampler_private.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\resampler_rom.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\resampler_structs.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\API.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\SigProc_FIX.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\structs.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\tables.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\tuning_parameters.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\typedef.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\x86\main_sse.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\x86\SigProc_FIX_sse.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\silk\VQ_WMat_EC.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\A2NLSF.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\ana_filt_bank_1.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\biquad_alt.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\bwexpander.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\bwexpander_32.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\check_control_input.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\CNG.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\code_signs.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\control_audio_bandwidth.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\control_codec.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\control_SNR.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\debug.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\dec_API.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decode_core.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decode_frame.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decode_indices.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decode_parameters.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decode_pitch.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decode_pulses.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\decoder_set_fs.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\enc_API.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\encode_indices.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\encode_pulses.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\gain_quant.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\HP_variable_cutoff.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\init_decoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\init_encoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\inner_prod_aligned.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\interpolate.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\lin2log.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\log2lin.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\LP_variable_cutoff.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\LPC_analysis_filter.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\LPC_inv_pred_gain.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_decode.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_del_dec_quant.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_encode.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_stabilize.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_unpack.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_VQ.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF_VQ_weights_laroia.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NLSF2A.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NSQ.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\NSQ_del_dec.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\pitch_est_tables.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\PLC.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\process_NLSFs.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\quant_LTP_gains.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_down2.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_down2_3.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_private_AR2.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_private_down_FIR.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_private_IIR_FIR.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_private_up2_HQ.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\resampler_rom.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\shell_coder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\sigm_Q15.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\sort.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\stereo_decode_pred.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\stereo_encode_pred.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\stereo_find_predictor.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\stereo_LR_to_MS.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\stereo_MS_to_LR.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\stereo_quant_pred.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\sum_sqr_shift.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\table_LSF_cos.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_gain.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_LTP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_NLSF_CB_NB_MB.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_NLSF_CB_WB.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_other.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_pitch_lag.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\tables_pulses_per_block.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\VAD.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\x86\NSQ_del_dec_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\x86\NSQ_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\x86\VAD_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\x86\VQ_WMat_EC_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\x86\x86_silk_map.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>
diff --git a/win32/VS2015/silk_fixed.vcxproj b/win32/VS2015/silk_fixed.vcxproj
deleted file mode 100644
index ba1b515..0000000
--- a/win32/VS2015/silk_fixed.vcxproj
+++ /dev/null
@@ -1,493 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugDLL|Win32">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugDLL|x64">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|Win32">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|x64">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{8484C90D-1561-402F-A91D-2DB10F8C5171}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>src_FIX</RootNamespace>
-    <ProjectName>silk_fixed</ProjectName>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../..;../../silk/fixed;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\include\opus_types.h" />
-    <ClInclude Include="..\..\win32\config.h" />
-    <ClInclude Include="..\..\silk\SigProc_FIX.h" />
-    <ClInclude Include="..\..\silk\fixed\main_FIX.h" />
-    <ClInclude Include="..\..\silk\fixed\structs_FIX.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\silk\fixed\apply_sine_window_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\autocorr_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\burg_modified_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\corrMatrix_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\encode_frame_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\find_LPC_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\find_LTP_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\find_pitch_lags_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\find_pred_coefs_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\k2a_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\k2a_Q16_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\LTP_analysis_filter_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\LTP_scale_ctrl_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\noise_shape_analysis_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\pitch_analysis_core_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\prefilter_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\process_gains_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\regularize_correlations_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\residual_energy16_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\residual_energy_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\schur64_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\schur_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\solve_LS_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\vector_ops_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\warped_autocorrelation_FIX.c" />
-    <ClCompile Include="..\..\silk\fixed\x86\burg_modified_FIX_sse.c" />
-    <ClCompile Include="..\..\silk\fixed\x86\prefilter_FIX_sse.c" />
-    <ClCompile Include="..\..\silk\fixed\x86\vector_ops_FIX_sse.c" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/silk_fixed.vcxproj.filters b/win32/VS2015/silk_fixed.vcxproj.filters
deleted file mode 100644
index c2327eb..0000000
--- a/win32/VS2015/silk_fixed.vcxproj.filters
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\win32\config.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\opus_types.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\SigProc_FIX.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\fixed\main_FIX.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\fixed\structs_FIX.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\silk\fixed\LTP_scale_ctrl_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\noise_shape_analysis_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\pitch_analysis_core_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\prefilter_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\process_gains_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\regularize_correlations_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\residual_energy_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\residual_energy16_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\schur_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\schur64_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\solve_LS_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\vector_ops_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\warped_autocorrelation_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\apply_sine_window_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\autocorr_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\burg_modified_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\corrMatrix_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\encode_frame_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\find_LPC_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\find_LTP_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\find_pitch_lags_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\find_pred_coefs_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\k2a_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\k2a_Q16_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\LTP_analysis_filter_FIX.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\x86\burg_modified_FIX_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\x86\prefilter_FIX_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\fixed\x86\vector_ops_FIX_sse.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/silk_float.vcxproj b/win32/VS2015/silk_float.vcxproj
deleted file mode 100644
index e55e76d..0000000
--- a/win32/VS2015/silk_float.vcxproj
+++ /dev/null
@@ -1,594 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugDLL|Win32">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugDLL|x64">
-      <Configuration>DebugDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Debug|x64">
-      <Configuration>Debug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|Win32">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="ReleaseDLL|x64">
-      <Configuration>ReleaseDLL</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{9C4961D2-5DDB-40C7-9BE8-CA918DC4E782}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>src_FLP</RootNamespace>
-    <ProjectName>silk_float</ProjectName>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <CustomBuildBeforeTargets>Compile</CustomBuildBeforeTargets>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <CustomBuildBeforeTargets>Compile</CustomBuildBeforeTargets>
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>../../silk/float;../../silk;../../win32;../../celt;../../include;../win32</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-    <Lib>
-      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-    <CustomBuildStep>
-      <Command>
-      </Command>
-    </CustomBuildStep>
-    <CustomBuildStep>
-      <Outputs>
-      </Outputs>
-    </CustomBuildStep>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\include\opus_types.h" />
-    <ClInclude Include="..\..\win32\config.h" />
-    <ClInclude Include="..\..\silk\float\main_FLP.h" />
-    <ClInclude Include="..\..\silk\float\SigProc_FLP.h" />
-    <ClInclude Include="..\..\silk\float\structs_FLP.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\silk\float\apply_sine_window_FLP.c" />
-    <ClCompile Include="..\..\silk\float\autocorrelation_FLP.c" />
-    <ClCompile Include="..\..\silk\float\burg_modified_FLP.c" />
-    <ClCompile Include="..\..\silk\float\bwexpander_FLP.c" />
-    <ClCompile Include="..\..\silk\float\corrMatrix_FLP.c" />
-    <ClCompile Include="..\..\silk\float\encode_frame_FLP.c" />
-    <ClCompile Include="..\..\silk\float\energy_FLP.c" />
-    <ClCompile Include="..\..\silk\float\find_LPC_FLP.c" />
-    <ClCompile Include="..\..\silk\float\find_LTP_FLP.c" />
-    <ClCompile Include="..\..\silk\float\find_pitch_lags_FLP.c" />
-    <ClCompile Include="..\..\silk\float\find_pred_coefs_FLP.c" />
-    <ClCompile Include="..\..\silk\float\inner_product_FLP.c" />
-    <ClCompile Include="..\..\silk\float\k2a_FLP.c" />
-    <ClCompile Include="..\..\silk\float\levinsondurbin_FLP.c" />
-    <ClCompile Include="..\..\silk\float\LPC_analysis_filter_FLP.c" />
-    <ClCompile Include="..\..\silk\float\LPC_inv_pred_gain_FLP.c" />
-    <ClCompile Include="..\..\silk\float\LTP_analysis_filter_FLP.c" />
-    <ClCompile Include="..\..\silk\float\LTP_scale_ctrl_FLP.c" />
-    <ClCompile Include="..\..\silk\float\noise_shape_analysis_FLP.c" />
-    <ClCompile Include="..\..\silk\float\pitch_analysis_core_FLP.c" />
-    <ClCompile Include="..\..\silk\float\prefilter_FLP.c" />
-    <ClCompile Include="..\..\silk\float\process_gains_FLP.c" />
-    <ClCompile Include="..\..\silk\float\regularize_correlations_FLP.c" />
-    <ClCompile Include="..\..\silk\float\residual_energy_FLP.c" />
-    <ClCompile Include="..\..\silk\float\scale_copy_vector_FLP.c" />
-    <ClCompile Include="..\..\silk\float\scale_vector_FLP.c" />
-    <ClCompile Include="..\..\silk\float\schur_FLP.c" />
-    <ClCompile Include="..\..\silk\float\solve_LS_FLP.c" />
-    <ClCompile Include="..\..\silk\float\sort_FLP.c" />
-    <ClCompile Include="..\..\silk\float\warped_autocorrelation_FLP.c" />
-    <ClCompile Include="..\..\silk\float\wrappers_FLP.c" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/silk_float.vcxproj.filters b/win32/VS2015/silk_float.vcxproj.filters
deleted file mode 100644
index 33d25ba..0000000
--- a/win32/VS2015/silk_float.vcxproj.filters
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\include\opus_types.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\win32\config.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\float\main_FLP.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\float\SigProc_FLP.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\silk\float\structs_FLP.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\silk\float\scale_vector_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\schur_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\solve_LS_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\sort_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\warped_autocorrelation_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\wrappers_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\apply_sine_window_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\autocorrelation_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\burg_modified_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\bwexpander_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\corrMatrix_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\encode_frame_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\energy_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\find_LPC_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\find_LTP_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\find_pitch_lags_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\find_pred_coefs_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\inner_product_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\k2a_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\levinsondurbin_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\LPC_analysis_filter_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\LPC_inv_pred_gain_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\LTP_analysis_filter_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\LTP_scale_ctrl_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\noise_shape_analysis_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\pitch_analysis_core_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\prefilter_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\process_gains_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\regularize_correlations_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\residual_energy_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\silk\float\scale_copy_vector_FLP.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/win32/VS2015/test_opus_api.vcxproj b/win32/VS2015/test_opus_api.vcxproj
index 302752d..7cae131 100644
--- a/win32/VS2015/test_opus_api.vcxproj
+++ b/win32/VS2015/test_opus_api.vcxproj
@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL_fixed|Win32">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL_fixed|x64">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugDLL|Win32">
       <Configuration>DebugDLL</Configuration>
       <Platform>Win32</Platform>
@@ -17,6 +25,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|Win32">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|x64">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="ReleaseDLL|Win32">
       <Configuration>ReleaseDLL</Configuration>
       <Platform>Win32</Platform>
@@ -38,76 +54,62 @@
     <ClCompile Include="..\..\tests\test_opus_api.c" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="celt.vcxproj">
-      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>
-    </ProjectReference>
     <ProjectReference Include="opus.vcxproj">
       <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
     </ProjectReference>
-    <ProjectReference Include="silk_common.vcxproj">
-      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>
-    </ProjectReference>
-    <ProjectReference Include="silk_float.vcxproj">
-      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>
-    </ProjectReference>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{1D257A17-D254-42E5-82D6-1C87A6EC775A}</ProjectGuid>
     <Keyword>Win32Proj</Keyword>
     <RootNamespace>test_opus_api</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -115,331 +117,54 @@
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
+  <ItemDefinitionGroup />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/win32/VS2015/test_opus_decode.vcxproj b/win32/VS2015/test_opus_decode.vcxproj
index ef6279c..df01dca 100644
--- a/win32/VS2015/test_opus_decode.vcxproj
+++ b/win32/VS2015/test_opus_decode.vcxproj
@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL_fixed|Win32">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL_fixed|x64">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugDLL|Win32">
       <Configuration>DebugDLL</Configuration>
       <Platform>Win32</Platform>
@@ -17,6 +25,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|Win32">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|x64">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="ReleaseDLL|Win32">
       <Configuration>ReleaseDLL</Configuration>
       <Platform>Win32</Platform>
@@ -38,76 +54,62 @@
     <ClCompile Include="..\..\tests\test_opus_decode.c" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="celt.vcxproj">
-      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>
-    </ProjectReference>
     <ProjectReference Include="opus.vcxproj">
       <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
     </ProjectReference>
-    <ProjectReference Include="silk_common.vcxproj">
-      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>
-    </ProjectReference>
-    <ProjectReference Include="silk_float.vcxproj">
-      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>
-    </ProjectReference>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{8578322A-1883-486B-B6FA-E0094B65C9F2}</ProjectGuid>
     <Keyword>Win32Proj</Keyword>
     <RootNamespace>test_opus_api</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -115,339 +117,54 @@
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
+  <ItemDefinitionGroup />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/win32/VS2015/test_opus_encode.vcxproj b/win32/VS2015/test_opus_encode.vcxproj
index e2fa725..405efee 100644
--- a/win32/VS2015/test_opus_encode.vcxproj
+++ b/win32/VS2015/test_opus_encode.vcxproj
@@ -1,6 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="DebugDLL_fixed|Win32">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugDLL_fixed|x64">
+      <Configuration>DebugDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="DebugDLL|Win32">
       <Configuration>DebugDLL</Configuration>
       <Platform>Win32</Platform>
@@ -17,6 +25,14 @@
       <Configuration>Debug</Configuration>
       <Platform>x64</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|Win32">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseDLL_fixed|x64">
+      <Configuration>ReleaseDLL_fixed</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="ReleaseDLL|Win32">
       <Configuration>ReleaseDLL</Configuration>
       <Platform>Win32</Platform>
@@ -35,79 +51,66 @@
     </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="..\..\tests\opus_encode_regressions.c" />
     <ClCompile Include="..\..\tests\test_opus_encode.c" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="celt.vcxproj">
-      <Project>{245603e3-f580-41a5-9632-b25fe3372cbf}</Project>
-    </ProjectReference>
     <ProjectReference Include="opus.vcxproj">
       <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
     </ProjectReference>
-    <ProjectReference Include="silk_common.vcxproj">
-      <Project>{c303d2fc-ff97-49b8-9ddd-467b4c9a0b16}</Project>
-    </ProjectReference>
-    <ProjectReference Include="silk_float.vcxproj">
-      <Project>{9c4961d2-5ddb-40c7-9be8-ca918dc4e782}</Project>
-    </ProjectReference>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{84DAA768-1A38-4312-BB61-4C78BB59E5B8}</ProjectGuid>
     <Keyword>Win32Proj</Keyword>
     <RootNamespace>test_opus_api</RootNamespace>
-    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v140</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -115,339 +118,54 @@
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL_fixed|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="common.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <IntDir>$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
-    <OutDir>$(Platform)\$(Configuration)\</OutDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>true</SDLCheck>
-      <MultiProcessorCompilation>false</MultiProcessorCompilation>
-      <InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
-      <OmitFramePointers>false</OmitFramePointers>
-      <StringPooling>false</StringPooling>
-      <SmallerTypeCheck>false</SmallerTypeCheck>
-      <ControlFlowGuard>Guard</ControlFlowGuard>
-      <FunctionLevelLinking>false</FunctionLevelLinking>
-      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
-      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
-      <FloatingPointExceptions>true</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Fast</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <AdditionalIncludeDirectories>..\..\silk;..\..\celt;..\;..\..\include;</AdditionalIncludeDirectories>
-      <DisableSpecificWarnings>4996</DisableSpecificWarnings>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <CompileAsManaged>false</CompileAsManaged>
-      <CompileAsWinRT>false</CompileAsWinRT>
-      <SDLCheck>false</SDLCheck>
-      <MultiProcessorCompilation>true</MultiProcessorCompilation>
-      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
-      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
-      <OmitFramePointers>true</OmitFramePointers>
-      <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
-      <StringPooling>true</StringPooling>
-      <ExceptionHandling>false</ExceptionHandling>
-      <StructMemberAlignment>16Bytes</StructMemberAlignment>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <ControlFlowGuard>false</ControlFlowGuard>
-      <EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
-      <FloatingPointModel>Precise</FloatingPointModel>
-      <FloatingPointExceptions>false</FloatingPointExceptions>
-      <RuntimeTypeInfo>false</RuntimeTypeInfo>
-      <OpenMPSupport>false</OpenMPSupport>
-    </ClCompile>
-    <Link>
-      <SubSystem>Console</SubSystem>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
+  <ItemDefinitionGroup />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/win32/VS2015/test_opus_encode.vcxproj.filters b/win32/VS2015/test_opus_encode.vcxproj.filters
index 84ef445..4ed3bb9 100644
--- a/win32/VS2015/test_opus_encode.vcxproj.filters
+++ b/win32/VS2015/test_opus_encode.vcxproj.filters
@@ -10,5 +10,8 @@
     <ClCompile Include="..\..\tests\test_opus_encode.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\tests\opus_encode_regressions.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/win32/genversion.bat b/win32/genversion.bat
index cd1d4dc..1def746 100644
--- a/win32/genversion.bat
+++ b/win32/genversion.bat
@@ -2,13 +2,13 @@
 
 setlocal enableextensions enabledelayedexpansion
 
-for /f %%v in ('git --git-dir="%~dp0..\.git" describe --tags --match "v*"') do set version=%%v
+for /f %%v in ('cd "%~dp0.." ^&^& git status ^>NUL 2^>NUL ^&^& git describe --tags --match "v*" --dirty 2^>NUL') do set version=%%v
 
-if not "%version%"=="" goto :gotversion
+if not "%version%"=="" set version=!version:~1! && goto :gotversion
 
-if exist "%~dp0..\version.mk" goto :getversion
+if exist "%~dp0..\package_version" goto :getversion
 
-echo Git cannot be found, nor can version.mk. Generating unknown version.
+echo Git cannot be found, nor can package_version. Generating unknown version.
 
 set version=unknown
 
@@ -16,25 +16,16 @@
 
 :getversion
 
-for /f "delims== tokens=2" %%v in (%~dps0..\version.mk) do set version=%%v
-
-set version=!version:^"=!
-set version=!version: =!
+for /f "delims== tokens=2" %%v in (%~dps0..\package_version) do set version=%%v
+set version=!version:"=!
 
 :gotversion
 
+set version=!version: =!
 set version_out=#define %~2 "%version%"
-set version_mk=%~2 = "%version%"
 
 echo %version_out%> "%~1_temp"
 
-if %version%==unknown goto :skipgenerate
-
-echo # static version string; update manually every release.> "%~dp0..\version.mk"
-echo %version_mk%>> "%~dp0..\version.mk"
-
-:skipgenerate
-
 echo n | comp "%~1_temp" "%~1" > NUL 2> NUL
 
 if not errorlevel 1 goto exit