Upgrade Opus to v1.3

Bug: 63932386
Test: - verified builds for arm*/x86*
      - checked functionality using an emulator and stagefright

Change-Id: I10c4b267be1c846d8992e3c5f6d2576c2cb258a9
Signed-off-by: Felicia Lim <flim@google.com>
diff --git a/Android.bp b/Android.bp
index 82f6a7c..fc6ddd4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -140,12 +140,15 @@
         "silk/fixed/schur_FIX.c",
 
         // OPUS_SOURCES
+        "src/mapping_matrix.c",
         "src/opus.c",
         "src/opus_decoder.c",
         "src/opus_encoder.c",
         "src/opus_multistream.c",
         "src/opus_multistream_encoder.c",
         "src/opus_multistream_decoder.c",
+        "src/opus_projection_encoder.c",
+        "src/opus_projection_decoder.c",
         "src/repacketizer.c",
 
         // OPUS_SOURCES_FLOAT
@@ -167,6 +170,7 @@
         "-DUSE_ALLOCA",
         "-DHAVE_LRINT",
         "-DHAVE_LRINTF",
+        "-DENABLE_HARDENING",
         "-O2",
         "-fno-math-errno",
         "-Wall",
@@ -261,19 +265,19 @@
             sse4_1: {
                 srcs: [
                     // CELT_SOURCES_SSE4_1
-                    "celt/x86/celt_lpc_sse.c",
+                    "celt/x86/celt_lpc_sse4_1.c",
                     "celt/x86/pitch_sse4_1.c",
 
                     // SILK_SOURCES_SSE4_1
-                    "silk/x86/NSQ_sse.c",
-                    "silk/x86/NSQ_del_dec_sse.c",
+                    "silk/x86/NSQ_sse4_1.c",
+                    "silk/x86/NSQ_del_dec_sse4_1.c",
                     "silk/x86/x86_silk_map.c",
-                    "silk/x86/VAD_sse.c",
-                    "silk/x86/VQ_WMat_EC_sse.c",
+                    "silk/x86/VAD_sse4_1.c",
+                    "silk/x86/VQ_WMat_EC_sse4_1.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/vector_ops_FIX_sse4_1.c",
+                    "silk/fixed/x86/burg_modified_FIX_sse4_1.c",
                 ],
 
                 cflags: [
@@ -293,6 +297,7 @@
 
                     // CELT_SOURCES_SSE2
                     "celt/x86/pitch_sse2.c",
+                    "celt/x86/vq_sse2.c",
                 ],
 
                 cflags: [
@@ -306,19 +311,19 @@
             sse4_1: {
                 srcs: [
                     // CELT_SOURCES_SSE4_1
-                    "celt/x86/celt_lpc_sse.c",
+                    "celt/x86/celt_lpc_sse4_1.c",
                     "celt/x86/pitch_sse4_1.c",
 
                     // SILK_SOURCES_SSE4_1
-                    "silk/x86/NSQ_sse.c",
-                    "silk/x86/NSQ_del_dec_sse.c",
+                    "silk/x86/NSQ_sse4_1.c",
+                    "silk/x86/NSQ_del_dec_sse4_1.c",
                     "silk/x86/x86_silk_map.c",
-                    "silk/x86/VAD_sse.c",
-                    "silk/x86/VQ_WMat_EC_sse.c",
+                    "silk/x86/VAD_sse4_1.c",
+                    "silk/x86/VQ_WMat_EC_sse4_1.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/vector_ops_FIX_sse4_1.c",
+                    "silk/fixed/x86/burg_modified_FIX_sse4_1.c",
                 ],
 
                 cflags: [
diff --git a/Makefile.am b/Makefile.am
index 5b57b33..9c09dec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -82,7 +82,7 @@
 libopus_la_LIBADD += libarmasm.la
 endif
 
-pkginclude_HEADERS = include/opus.h include/opus_multistream.h include/opus_types.h include/opus_defines.h
+pkginclude_HEADERS = include/opus.h include/opus_multistream.h include/opus_types.h include/opus_defines.h include/opus_projection.h
 
 noinst_HEADERS = $(OPUS_HEAD) $(SILK_HEAD) $(CELT_HEAD)
 
@@ -102,7 +102,8 @@
                   tests/test_opus_api \
                   tests/test_opus_decode \
                   tests/test_opus_encode \
-                  tests/test_opus_padding
+                  tests/test_opus_padding \
+                  tests/test_opus_projection
 
 TESTS = celt/tests/test_unit_cwrs32 \
         celt/tests/test_unit_dft \
@@ -116,7 +117,8 @@
         tests/test_opus_api \
         tests/test_opus_decode \
         tests/test_opus_encode \
-        tests/test_opus_padding
+        tests/test_opus_padding \
+        tests/test_opus_projection
 
 opus_demo_SOURCES = src/opus_demo.c
 
@@ -143,6 +145,13 @@
 
 CELT_OBJ = $(CELT_SOURCES:.c=.lo)
 SILK_OBJ = $(SILK_SOURCES:.c=.lo)
+OPUS_OBJ = $(OPUS_SOURCES:.c=.lo)
+
+tests_test_opus_projection_SOURCES = tests/test_opus_projection.c tests/test_opus_common.h
+tests_test_opus_projection_LDADD = $(OPUS_OBJ) $(SILK_OBJ) $(CELT_OBJ) $(NE10_LIBS) $(LIBM)
+if OPUS_ARM_EXTERNAL_ASM
+tests_test_opus_projection_LDADD += libarmasm.la
+endif
 
 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)
diff --git a/README b/README
index f09766d..27fddf9 100644
--- a/README
+++ b/README
@@ -29,7 +29,7 @@
 
 Opus stored in files should use the Ogg encapsulation for Opus which is
 described at:
- https://wiki.xiph.org/OggOpus
+ https://tools.ietf.org/html/rfc7845
 
 An opus-tools package is available which provides encoding and decoding of
 Ogg encapsulated Opus files and includes a number of useful features.
@@ -125,13 +125,13 @@
 
 There is also collection of standard test vectors which are not
 included in this package for size reasons but can be obtained from:
-https://opus-codec.org/testvectors/opus_testvectors.tar.gz
+https://opus-codec.org/docs/opus_testvectors-rfc8251.tar.gz
 
 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 -OL https://opus-codec.org/docs/opus_testvectors-rfc8251.tar.gz
+    % tar -zxf opus_testvectors-rfc8251.tar.gz
+    % ./tests/run_vectors.sh ./ opus_newvectors 48000
 
 == Portability notes ==
 
diff --git a/README.android b/README.android
index bcee085..06fdc0e 100644
--- a/README.android
+++ b/README.android
@@ -1,4 +1,4 @@
-* current source is based on libopus 1.2.1 (https://git.xiph.org/?p=opus.git;a=snapshot;h=defbc370ec764d3d0dc43c45911e455b5e483b30;sf=tgz)
+* current source is based on libopus 1.3 (https://git.xiph.org/?p=opus.git;a=snapshot;h=83d5155f151ca47c9d6274ded1a7481f746b9a43;sf=tgz)
 * libopus is BSD-licensed - http://www.opus-codec.org/license/
 
 Updating:
diff --git a/README.version b/README.version
index e4691e6..77ed7aa 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,3 @@
-URL: https://git.xiph.org/?p=opus.git;a=snapshot;h=defbc370ec764d3d0dc43c45911e455b5e483b30;sf=tgz
-Version: 1.2.1
+URL: https://git.xiph.org/?p=opus.git;a=snapshot;h=83d5155f151ca47c9d6274ded1a7481f746b9a43;sf=tgz
+Version: 1.3
 BugComponent: 25690
diff --git a/celt/arch.h b/celt/arch.h
index d1e6457..c627a74 100644
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -56,23 +56,40 @@
 
 #define CELT_SIG_SCALE 32768.f
 
-#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
-#ifdef ENABLE_ASSERTIONS
+#define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__);
+
+#if defined(ENABLE_ASSERTIONS) || defined(ENABLE_HARDENING)
+#ifdef __GNUC__
+__attribute__((noreturn))
+#endif
+void celt_fatal(const char *str, const char *file, int line);
+
+#if defined(CELT_C) && !defined(OVERRIDE_celt_fatal)
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef __GNUC__
 __attribute__((noreturn))
 #endif
-static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
+void celt_fatal(const char *str, const char *file, int line)
 {
    fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
    abort();
 }
-#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
-#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}}
+#endif
+
+#define celt_assert(cond) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond);}}
+#define celt_assert2(cond, message) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond "\n" message);}}
+#define MUST_SUCCEED(call) celt_assert((call) == OPUS_OK)
 #else
 #define celt_assert(cond)
 #define celt_assert2(cond, message)
+#define MUST_SUCCEED(call) do {if((call) != OPUS_OK) {RESTORE_STACK; return OPUS_INTERNAL_ERROR;} } while (0)
+#endif
+
+#if defined(ENABLE_ASSERTIONS)
+#define celt_sig_assert(cond) {if (!(cond)) {CELT_FATAL("signal assertion failed: " #cond);}}
+#else
+#define celt_sig_assert(cond)
 #endif
 
 #define IMUL32(a,b) ((a)*(b))
@@ -107,6 +124,8 @@
 typedef opus_val16 celt_norm;
 typedef opus_val32 celt_ener;
 
+#define celt_isnan(x) 0
+
 #define Q15ONE 32767
 
 #define SIG_SHIFT 12
diff --git a/celt/arm/celt_ne10_fft.c b/celt/arm/celt_fft_ne10.c
similarity index 99%
rename from celt/arm/celt_ne10_fft.c
rename to celt/arm/celt_fft_ne10.c
index b8c60ab..ea5fd78 100644
--- a/celt/arm/celt_ne10_fft.c
+++ b/celt/arm/celt_fft_ne10.c
@@ -1,7 +1,7 @@
 /* Copyright (c) 2015 Xiph.Org Foundation
    Written by Viswanath Puttagunta */
 /**
-   @file celt_ne10_fft.c
+   @file celt_fft_ne10.c
    @brief ARM Neon optimizations for fft using NE10 library
  */
 
diff --git a/celt/arm/celt_ne10_mdct.c b/celt/arm/celt_mdct_ne10.c
similarity index 99%
rename from celt/arm/celt_ne10_mdct.c
rename to celt/arm/celt_mdct_ne10.c
index 293c3ef..3531d02 100644
--- a/celt/arm/celt_ne10_mdct.c
+++ b/celt/arm/celt_mdct_ne10.c
@@ -1,7 +1,7 @@
 /* Copyright (c) 2015 Xiph.Org Foundation
    Written by Viswanath Puttagunta */
 /**
-   @file celt_ne10_mdct.c
+   @file celt_mdct_ne10.c
    @brief ARM Neon optimizations for mdct using NE10 library
  */
 
diff --git a/celt/arm/celt_neon_intr.c b/celt/arm/celt_neon_intr.c
index cf44398..effda76 100644
--- a/celt/arm/celt_neon_intr.c
+++ b/celt/arm/celt_neon_intr.c
@@ -196,7 +196,7 @@
    int i;
    (void)arch;
    celt_assert(max_pitch > 0);
-   celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
+   celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
 
    for (i = 0; i < (max_pitch-3); i += 4) {
       xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,
diff --git a/celt/arm/pitch_arm.h b/celt/arm/pitch_arm.h
index 4ee13bd..bed8b04 100644
--- a/celt/arm/pitch_arm.h
+++ b/celt/arm/pitch_arm.h
@@ -90,7 +90,9 @@
 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
       const opus_val16 *, opus_val32 *, int, int, int);
 #   define OVERRIDE_PITCH_XCORR (1)
-#   define celt_pitch_xcorr (*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])
+#   define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
+  ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
+        xcorr, len, max_pitch, arch))
 
 #  elif defined(OPUS_ARM_PRESUME_EDSP) || \
     defined(OPUS_ARM_PRESUME_MEDIA) || \
@@ -142,7 +144,9 @@
       const opus_val16 *, opus_val32 *, int, int, int);
 
 #  define OVERRIDE_PITCH_XCORR (1)
-#  define celt_pitch_xcorr (*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])
+#  define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
+  ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
+        xcorr, len, max_pitch, arch))
 
 #  elif defined(OPUS_ARM_PRESUME_NEON_INTR)
 
diff --git a/celt/bands.c b/celt/bands.c
index 3b1f5cf..f7bb66a 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -70,10 +70,10 @@
    opus_int32 tmp;
    opus_int16 x2;
    tmp = (4096+((opus_int32)(x)*(x)))>>13;
-   celt_assert(tmp<=32767);
+   celt_sig_assert(tmp<=32767);
    x2 = tmp;
    x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));
-   celt_assert(x2<=32766);
+   celt_sig_assert(x2<=32766);
    return 1+x2;
 }
 
@@ -282,7 +282,7 @@
 
       N0 = m->eBands[i+1]-m->eBands[i];
       /* depth in 1/8 bits */
-      celt_assert(pulses[i]>=0);
+      celt_sig_assert(pulses[i]>=0);
       depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM;
 
 #ifdef FIXED_POINT
@@ -478,7 +478,7 @@
 /* Decide whether we should spread the pulses in the current frame */
 int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
       int last_decision, int *hf_average, int *tapset_decision, int update_hf,
-      int end, int C, int M)
+      int end, int C, int M, const int *spread_weight)
 {
    int i, c, N0;
    int sum = 0, nbBands=0;
@@ -519,8 +519,8 @@
          if (i>m->nbEBands-4)
             hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N);
          tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
-         sum += tmp*256;
-         nbBands++;
+         sum += tmp*spread_weight[i];
+         nbBands+=spread_weight[i];
       }
    } while (++c<C);
 
@@ -544,7 +544,7 @@
    /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/
    celt_assert(nbBands>0); /* end has to be non-zero */
    celt_assert(sum>=0);
-   sum = celt_udiv(sum, nbBands);
+   sum = celt_udiv((opus_int32)sum<<8, nbBands);
    /* Recursive averaging */
    sum = (sum+*average)>>1;
    *average = sum;
@@ -1492,6 +1492,7 @@
       else
          Y = NULL;
       N = M*eBands[i+1]-M*eBands[i];
+      celt_assert(N > 0);
       tell = ec_tell_frac(ec);
 
       /* Compute how many bits we want to allocate to this band */
@@ -1507,7 +1508,7 @@
          b = 0;
       }
 
-#ifdef ENABLE_UPDATE_DRAFT
+#ifndef DISABLE_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)
@@ -1541,7 +1542,7 @@
          fold_start = lowband_offset;
          while(M*eBands[--fold_start] > effective_lowband+norm_offset);
          fold_end = lowband_offset-1;
-#ifdef ENABLE_UPDATE_DRAFT
+#ifndef DISABLE_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);
@@ -1621,8 +1622,10 @@
                ctx = ctx_save;
                OPUS_COPY(X, X_save, N);
                OPUS_COPY(Y, Y_save, N);
+#ifndef DISABLE_UPDATE_DRAFT
                if (i == start+1)
                   special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
+#endif
                /* Encode and round up. */
                ctx.theta_round = 1;
                x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
diff --git a/celt/bands.h b/celt/bands.h
index 2488c18..422b32c 100644
--- a/celt/bands.h
+++ b/celt/bands.h
@@ -72,7 +72,7 @@
 
 int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
       int last_decision, int *hf_average, int *tapset_decision, int update_hf,
-      int end, int C, int M);
+      int end, int C, int M, const int *spread_weight);
 
 #ifdef MEASURE_NORM_MSE
 void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
diff --git a/celt/celt.h b/celt/celt.h
index 7017530..24b6b2b 100644
--- a/celt/celt.h
+++ b/celt/celt.h
@@ -59,9 +59,11 @@
    float noisiness;
    float activity;
    float music_prob;
-   float vad_prob;
+   float music_prob_min;
+   float music_prob_max;
    int   bandwidth;
    float activity_probability;
+   float max_pitch_ratio;
    /* Store as Q6 char to save space. */
    unsigned char leak_boost[LEAK_BANDS];
 } AnalysisInfo;
@@ -207,6 +209,13 @@
 
 extern const signed char tf_select_table[4][8];
 
+#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
+void validate_celt_decoder(CELTDecoder *st);
+#define VALIDATE_CELT_DECODER(st) validate_celt_decoder(st)
+#else
+#define VALIDATE_CELT_DECODER(st)
+#endif
+
 int resampling_factor(opus_int32 rate);
 
 void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c
index 567d745..e6efce9 100644
--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -51,6 +51,14 @@
 #include "celt_lpc.h"
 #include "vq.h"
 
+/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
+   CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
+   current value corresponds to a pitch of 66.67 Hz. */
+#define PLC_PITCH_LAG_MAX (720)
+/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
+   pitch of 480 Hz. */
+#define PLC_PITCH_LAG_MIN (100)
+
 #if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
 #define NORM_ALIASING_HACK
 #endif
@@ -101,6 +109,38 @@
    /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
 };
 
+#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
+/* Make basic checks on the CELT state to ensure we don't end
+   up writing all over memory. */
+void validate_celt_decoder(CELTDecoder *st)
+{
+#ifndef CUSTOM_MODES
+   celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL));
+   celt_assert(st->overlap == 120);
+#endif
+   celt_assert(st->channels == 1 || st->channels == 2);
+   celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
+   celt_assert(st->downsample > 0);
+   celt_assert(st->start == 0 || st->start == 17);
+   celt_assert(st->start < st->end);
+   celt_assert(st->end <= 21);
+#ifdef OPUS_ARCHMASK
+   celt_assert(st->arch >= 0);
+   celt_assert(st->arch <= OPUS_ARCHMASK);
+#endif
+   celt_assert(st->last_pitch_index <= PLC_PITCH_LAG_MAX);
+   celt_assert(st->last_pitch_index >= PLC_PITCH_LAG_MIN || st->last_pitch_index == 0);
+   celt_assert(st->postfilter_period < MAX_PERIOD);
+   celt_assert(st->postfilter_period >= COMBFILTER_MINPERIOD || st->postfilter_period == 0);
+   celt_assert(st->postfilter_period_old < MAX_PERIOD);
+   celt_assert(st->postfilter_period_old >= COMBFILTER_MINPERIOD || st->postfilter_period_old == 0);
+   celt_assert(st->postfilter_tapset <= 2);
+   celt_assert(st->postfilter_tapset >= 0);
+   celt_assert(st->postfilter_tapset_old <= 2);
+   celt_assert(st->postfilter_tapset_old >= 0);
+}
+#endif
+
 int celt_decoder_get_size(int channels)
 {
    const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
@@ -164,7 +204,7 @@
    st->start = 0;
    st->end = st->mode->effEBands;
    st->signalling = 1;
-#ifdef ENABLE_UPDATE_DRAFT
+#ifndef DISABLE_UPDATE_DRAFT
    st->disable_inv = channels == 1;
 #else
    st->disable_inv = 0;
@@ -437,14 +477,6 @@
    }
 }
 
-/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
-   CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
-   current value corresponds to a pitch of 66.67 Hz. */
-#define PLC_PITCH_LAG_MAX (720)
-/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
-   pitch of 480 Hz. */
-#define PLC_PITCH_LAG_MIN (100)
-
 static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
 {
    int pitch_index;
@@ -554,6 +586,7 @@
 
       celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);
    } else {
+      int exc_length;
       /* Pitch-based PLC */
       const opus_val16 *window;
       opus_val16 *exc;
@@ -561,6 +594,7 @@
       int pitch_index;
       VARDECL(opus_val32, etmp);
       VARDECL(opus_val16, _exc);
+      VARDECL(opus_val16, fir_tmp);
 
       if (loss_count == 0)
       {
@@ -570,8 +604,13 @@
          fade = QCONST16(.8f,15);
       }
 
+      /* 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. */
+      exc_length = IMIN(2*pitch_index, MAX_PERIOD);
+
       ALLOC(etmp, overlap, opus_val32);
       ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
+      ALLOC(fir_tmp, exc_length, opus_val16);
       exc = _exc+LPC_ORDER;
       window = mode->window;
       c=0; do {
@@ -581,13 +620,11 @@
          celt_sig *buf;
          int extrapolation_offset;
          int extrapolation_len;
-         int exc_length;
          int j;
 
          buf = decode_mem[c];
-         for (i=0;i<MAX_PERIOD;i++) {
-            exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT);
-         }
+         for (i=0;i<MAX_PERIOD+LPC_ORDER;i++)
+            exc[i-LPC_ORDER] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD-LPC_ORDER+i], SIG_SHIFT);
 
          if (loss_count == 0)
          {
@@ -631,20 +668,14 @@
          }
 #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. */
-         exc_length = IMIN(2*pitch_index, MAX_PERIOD);
          /* Initialize the LPC history with the samples just before the start
             of the region for which we're computing the excitation. */
          {
-            for (i=0;i<LPC_ORDER;i++)
-            {
-               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. */
+            /* Compute the excitation for exc_length samples before the loss. We need the copy
+               because celt_fir() cannot filter in-place. */
             celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
-                  exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, st->arch);
+                  fir_tmp, exc_length, LPC_ORDER, st->arch);
+            OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length);
          }
 
          /* Check if the waveform is decaying, and if so how fast.
@@ -833,6 +864,7 @@
    const opus_int16 *eBands;
    ALLOC_STACK;
 
+   VALIDATE_CELT_DECODER(st);
    mode = st->mode;
    nbEBands = mode->nbEBands;
    overlap = mode->overlap;
@@ -1027,7 +1059,7 @@
    ALLOC(pulses, nbEBands, int);
    ALLOC(fine_priority, nbEBands, int);
 
-   codedBands = compute_allocation(mode, start, end, offsets, cap,
+   codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
          alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
          fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
 
diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c
index 053e5a3..44cb085 100644
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -362,6 +362,12 @@
       /* Compute harmonic mean discarding the unreliable boundaries
          The data is smooth, so we only take 1/4th of the samples */
       unmask=0;
+      /* We should never see NaNs here. If we find any, then something really bad happened and we better abort
+         before it does any damage later on. If these asserts are disabled (no hardening), then the table
+         lookup a few lines below (id = ...) is likely to crash dur to an out-of-bounds read. DO NOT FIX
+         that crash on NaN since it could result in a worse issue later on. */
+      celt_assert(!celt_isnan(tmp[0]));
+      celt_assert(!celt_isnan(norm));
       for (i=12;i<len2-5;i+=4)
       {
          int id;
@@ -577,7 +583,7 @@
 
 static int tf_analysis(const CELTMode *m, int len, int isTransient,
       int *tf_res, int lambda, celt_norm *X, int N0, int LM,
-      opus_val16 tf_estimate, int tf_chan)
+      opus_val16 tf_estimate, int tf_chan, int *importance)
 {
    int i;
    VARDECL(int, metric);
@@ -660,22 +666,22 @@
          biasing the decision */
       if (narrow && (metric[i]==0 || metric[i]==-2*LM))
          metric[i]-=1;
-      /*printf("%d ", metric[i]);*/
+      /*printf("%d ", metric[i]/2 + (!isTransient)*LM);*/
    }
    /*printf("\n");*/
    /* Search for the optimal tf resolution, including tf_select */
    tf_select = 0;
    for (sel=0;sel<2;sel++)
    {
-      cost0 = 0;
-      cost1 = isTransient ? 0 : lambda;
+      cost0 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
+      cost1 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*sel+1]) + (isTransient ? 0 : lambda);
       for (i=1;i<len;i++)
       {
          int curr0, curr1;
          curr0 = IMIN(cost0, cost1 + lambda);
          curr1 = IMIN(cost0 + lambda, cost1);
-         cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
-         cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);
+         cost0 = curr0 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
+         cost1 = curr1 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);
       }
       cost0 = IMIN(cost0, cost1);
       selcost[sel]=cost0;
@@ -684,8 +690,8 @@
     * If tests confirm it's useful for non-transients, we could allow it. */
    if (selcost[1]<selcost[0] && isTransient)
       tf_select=1;
-   cost0 = 0;
-   cost1 = isTransient ? 0 : lambda;
+   cost0 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
+   cost1 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]) + (isTransient ? 0 : lambda);
    /* Viterbi forward pass */
    for (i=1;i<len;i++)
    {
@@ -713,8 +719,8 @@
          curr1 = from1;
          path1[i]= 1;
       }
-      cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
-      cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);
+      cost0 = curr0 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
+      cost1 = curr1 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);
    }
    tf_res[len-1] = cost0 < cost1 ? 0 : 1;
    /* Viterbi backward pass to check the decisions */
@@ -964,7 +970,8 @@
 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, AnalysisInfo *analysis)
+      int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc,
+      AnalysisInfo *analysis, int *importance, int *spread_weight)
 {
    int i, c;
    opus_int32 tot_boost=0;
@@ -990,6 +997,42 @@
       for (i=0;i<end;i++)
          maxDepth = MAX16(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]);
    } while (++c<C);
+   {
+      /* Compute a really simple masking model to avoid taking into account completely masked
+         bands when computing the spreading decision. */
+      VARDECL(opus_val16, mask);
+      VARDECL(opus_val16, sig);
+      ALLOC(mask, nbEBands, opus_val16);
+      ALLOC(sig, nbEBands, opus_val16);
+      for (i=0;i<end;i++)
+         mask[i] = bandLogE[i]-noise_floor[i];
+      if (C==2)
+      {
+         for (i=0;i<end;i++)
+            mask[i] = MAX16(mask[i], bandLogE[nbEBands+i]-noise_floor[i]);
+      }
+      OPUS_COPY(sig, mask, end);
+      for (i=1;i<end;i++)
+         mask[i] = MAX16(mask[i], mask[i-1] - QCONST16(2.f, DB_SHIFT));
+      for (i=end-2;i>=0;i--)
+         mask[i] = MAX16(mask[i], mask[i+1] - QCONST16(3.f, DB_SHIFT));
+      for (i=0;i<end;i++)
+      {
+         /* Compute SMR: Mask is never more than 72 dB below the peak and never below the noise floor.*/
+         opus_val16 smr = sig[i]-MAX16(MAX16(0, maxDepth-QCONST16(12.f, DB_SHIFT)), mask[i]);
+         /* Clamp SMR to make sure we're not shifting by something negative or too large. */
+#ifdef FIXED_POINT
+         /* FIXME: Use PSHR16() instead */
+         int shift = -PSHR32(MAX16(-QCONST16(5.f, DB_SHIFT), MIN16(0, smr)), DB_SHIFT);
+#else
+         int shift = IMIN(5, IMAX(0, -(int)floor(.5f + smr)));
+#endif
+         spread_weight[i] = 32 >> shift;
+      }
+      /*for (i=0;i<end;i++)
+         printf("%d ", spread_weight[i]);
+      printf("\n");*/
+   }
    /* Make sure that dynamic allocation can't make us bust the budget */
    if (effectiveBytes > 50 && LM>=1 && !lfe)
    {
@@ -1046,6 +1089,14 @@
       }
       for (i=start;i<end;i++)
          follower[i] = MAX16(follower[i], surround_dynalloc[i]);
+      for (i=start;i<end;i++)
+      {
+#ifdef FIXED_POINT
+         importance[i] = PSHR32(13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))), 16);
+#else
+         importance[i] = (int)floor(.5f+13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))));
+#endif
+      }
       /* For non-transient CBR/CVBR frames, halve the dynalloc contribution */
       if ((!vbr || constrained_vbr)&&!isTransient)
       {
@@ -1101,6 +1152,9 @@
             tot_boost += boost_bits;
          }
       }
+   } else {
+      for (i=start;i<end;i++)
+         importance[i] = 13;
    }
    *tot_boost_ = tot_boost;
    RESTORE_STACK;
@@ -1109,7 +1163,7 @@
 
 
 static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, int CC, int N,
-      int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes)
+      int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes, AnalysisInfo *analysis)
 {
    int c;
    VARDECL(celt_sig, _pre);
@@ -1165,7 +1219,12 @@
       gain1 = 0;
       pitch_index = COMBFILTER_MINPERIOD;
    }
-
+#ifndef DISABLE_FLOAT_API
+   if (analysis->valid)
+      gain1 = (opus_val16)(gain1 * analysis->max_pitch_ratio);
+#else
+   (void)analysis;
+#endif
    /* Gain threshold for enabling the prefilter/postfilter */
    pf_threshold = QCONST16(.2f,15);
 
@@ -1362,6 +1421,8 @@
    VARDECL(int, pulses);
    VARDECL(int, cap);
    VARDECL(int, offsets);
+   VARDECL(int, importance);
+   VARDECL(int, spread_weight);
    VARDECL(int, fine_priority);
    VARDECL(int, tf_res);
    VARDECL(unsigned char, collapse_masks);
@@ -1414,6 +1475,7 @@
    opus_int32 equiv_rate;
    int hybrid;
    int weak_transient = 0;
+   int enable_tf_analysis;
    VARDECL(opus_val16, surround_dynalloc);
    ALLOC_STACK;
 
@@ -1454,7 +1516,7 @@
       tell0_frac=tell=1;
       nbFilledBytes=0;
    } else {
-      tell0_frac=tell=ec_tell_frac(enc);
+      tell0_frac=ec_tell_frac(enc);
       tell=ec_tell(enc);
       nbFilledBytes=(tell+4)>>3;
    }
@@ -1603,7 +1665,7 @@
             && 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);
+      pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes, &st->analysis);
       if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3)
             && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period))
          pitch_change = 1;
@@ -1633,7 +1695,7 @@
       /* 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;
+      int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.signalType != 2;
       isTransient = transient_analysis(in, N+overlap, CC,
             &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient);
    }
@@ -1662,6 +1724,9 @@
    }
 
    compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
+   /* This should catch any NaN in the CELT input. Since we're not supposed to see any (they're filtered
+      at the Opus layer), just abort. */
+   celt_assert(!celt_isnan(freq[0]) && (C==1 || !celt_isnan(freq[N])));
    if (CC==2&&C==1)
       tf_chan = 0;
    compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
@@ -1805,13 +1870,23 @@
    /* Band normalisation */
    normalise_bands(mode, freq, X, bandE, effEnd, C, M);
 
+   enable_tf_analysis = effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe;
+
+   ALLOC(offsets, nbEBands, int);
+   ALLOC(importance, nbEBands, int);
+   ALLOC(spread_weight, nbEBands, int);
+
+   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, &st->analysis, importance, spread_weight);
+
    ALLOC(tf_res, nbEBands, int);
    /* Disable variable tf resolution for hybrid and at very low bitrate */
-   if (effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe)
+   if (enable_tf_analysis)
    {
       int lambda;
-      lambda = IMAX(5, 1280/effectiveBytes + 2);
-      tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan);
+      lambda = IMAX(80, 20480/effectiveBytes + 2);
+      tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan, importance);
       for (i=effEnd;i<end;i++)
          tf_res[i] = tf_res[effEnd-1];
    } else if (hybrid && weak_transient)
@@ -1822,7 +1897,7 @@
       for (i=0;i<end;i++)
          tf_res[i] = 1;
       tf_select=0;
-   } else if (hybrid && effectiveBytes<15)
+   } else if (hybrid && effectiveBytes<15 && st->silk_info.signalType != 2)
    {
       /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */
       for (i=0;i<end;i++)
@@ -1893,7 +1968,7 @@
          {
             st->spread_decision = spreading_decision(mode, X,
                   &st->tonal_average, st->spread_decision, &st->hf_average,
-                  &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
+                  &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M, spread_weight);
          }
          /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/
          /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/
@@ -1901,11 +1976,6 @@
       ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
    }
 
-   ALLOC(offsets, nbEBands, int);
-
-   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, &st->analysis);
    /* For LFE, everything interesting is in the first band */
    if (st->lfe)
       offsets[0] = IMIN(8, effectiveBytes/3);
@@ -2121,7 +2191,7 @@
 #endif
    if (st->lfe)
       signalBandwidth = 1;
-   codedBands = compute_allocation(mode, start, end, offsets, cap,
+   codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
          alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses,
          fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth);
    if (st->lastCodedBands)
diff --git a/celt/celt_lpc.c b/celt/celt_lpc.c
index 57bc5f3..8ecb693 100644
--- a/celt/celt_lpc.c
+++ b/celt/celt_lpc.c
@@ -99,7 +99,7 @@
    int i,j;
    VARDECL(opus_val16, rnum);
    SAVE_STACK;
-
+   celt_assert(x != y);
    ALLOC(rnum, ord, opus_val16);
    for(i=0;i<ord;i++)
       rnum[i] = num[ord-i-1];
@@ -107,7 +107,7 @@
    {
       opus_val32 sum[4];
       sum[0] = SHL32(EXTEND32(x[i  ]), SIG_SHIFT);
-      sum[1] = SHL32(EXTEND32(x[i+1]), 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);
diff --git a/celt/cwrs.c b/celt/cwrs.c
index 9722f0a..a552e4f 100644
--- a/celt/cwrs.c
+++ b/celt/cwrs.c
@@ -482,7 +482,7 @@
       k0=_k;
       q=row[_n];
       if(q>_i){
-        celt_assert(p>q);
+        celt_sig_assert(p>q);
         _k=_n;
         do p=CELT_PVQ_U_ROW[--_k][_n];
         while(p>_i);
diff --git a/celt/entcode.h b/celt/entcode.h
index 13d6c84..3763e3f 100644
--- a/celt/entcode.h
+++ b/celt/entcode.h
@@ -122,7 +122,7 @@
 
 /* Tested exhaustively for all n and for 1<=d<=256 */
 static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
-   celt_assert(d>0);
+   celt_sig_assert(d>0);
 #ifdef USE_SMALL_DIV_TABLE
    if (d>256)
       return n/d;
@@ -138,7 +138,7 @@
 }
 
 static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) {
-   celt_assert(d>0);
+   celt_sig_assert(d>0);
 #ifdef USE_SMALL_DIV_TABLE
    if (n<0)
       return -(opus_int32)celt_udiv(-n, d);
diff --git a/celt/entdec.h b/celt/entdec.h
index d8ab318..025fc18 100644
--- a/celt/entdec.h
+++ b/celt/entdec.h
@@ -85,7 +85,7 @@
   The bits must have been encoded with ec_enc_uint().
   No call to ec_dec_update() is necessary after this call.
   _ft: The number of integers that can be decoded (one more than the max).
-       This must be at least one, and no more than 2**32-1.
+       This must be at least 2, and no more than 2**32-1.
   Return: The decoded bits.*/
 opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
 
diff --git a/celt/entenc.h b/celt/entenc.h
index 796bc4d..f502eaf 100644
--- a/celt/entenc.h
+++ b/celt/entenc.h
@@ -67,7 +67,7 @@
 /*Encodes a raw unsigned integer in the stream.
   _fl: The integer to encode.
   _ft: The number of integers that can be encoded (one more than the max).
-       This must be at least one, and no more than 2**32-1.*/
+       This must be at least 2, and no more than 2**32-1.*/
 void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);
 
 /*Encodes a sequence of raw bits in the stream.
diff --git a/celt/float_cast.h b/celt/float_cast.h
index 98b40ab..f218e86 100644
--- a/celt/float_cast.h
+++ b/celt/float_cast.h
@@ -96,7 +96,7 @@
 #include <math.h>
 #define float2int(x) lrint(x)
 
-#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_X64)
+#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1))
         #include <xmmintrin.h>
 
         __inline long int float2int(float value)
diff --git a/celt/mathops.c b/celt/mathops.c
index 21a01f5..6ee9b9e 100644
--- a/celt/mathops.c
+++ b/celt/mathops.c
@@ -38,7 +38,8 @@
 #include "mathops.h"
 
 /*Compute floor(sqrt(_val)) with exact arithmetic.
-  This has been tested on all possible 32-bit inputs.*/
+  _val must be greater than 0.
+  This has been tested on all possible 32-bit inputs greater than 0.*/
 unsigned isqrt32(opus_uint32 _val){
   unsigned b;
   unsigned g;
@@ -182,7 +183,7 @@
    int i;
    opus_val16 n;
    opus_val16 r;
-   celt_assert2(x>0, "celt_rcp() only defined for positive values");
+   celt_sig_assert(x>0);
    i = celt_ilog2(x);
    /* n is Q15 with range [0,1). */
    n = VSHR32(x,i-15)-32768;
diff --git a/celt/mathops.h b/celt/mathops.h
index 1f8a20c..5e86ff0 100644
--- a/celt/mathops.h
+++ b/celt/mathops.h
@@ -72,7 +72,7 @@
 #undef cA
 #undef cB
 #undef cC
-#undef cD
+#undef cE
 #endif
 
 
@@ -179,7 +179,7 @@
 /** Integer log in base2. Undefined for zero and negative numbers */
 static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x)
 {
-   celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
+   celt_sig_assert(x>0);
    return EC_ILOG(x)-1;
 }
 #endif
diff --git a/celt/pitch.c b/celt/pitch.c
index 5b061d8..872582a 100644
--- a/celt/pitch.c
+++ b/celt/pitch.c
@@ -102,11 +102,9 @@
    }
 }
 
-static void celt_fir5(const opus_val16 *x,
+static void celt_fir5(opus_val16 *x,
          const opus_val16 *num,
-         opus_val16 *y,
-         int N,
-         opus_val16 *mem)
+         int N)
 {
    int i;
    opus_val16 num0, num1, num2, num3, num4;
@@ -116,11 +114,11 @@
    num2=num[2];
    num3=num[3];
    num4=num[4];
-   mem0=mem[0];
-   mem1=mem[1];
-   mem2=mem[2];
-   mem3=mem[3];
-   mem4=mem[4];
+   mem0=0;
+   mem1=0;
+   mem2=0;
+   mem3=0;
+   mem4=0;
    for (i=0;i<N;i++)
    {
       opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
@@ -134,13 +132,8 @@
       mem2 = mem1;
       mem1 = mem0;
       mem0 = x[i];
-      y[i] = ROUND16(sum, SIG_SHIFT);
+      x[i] = ROUND16(sum, SIG_SHIFT);
    }
-   mem[0]=mem0;
-   mem[1]=mem1;
-   mem[2]=mem2;
-   mem[3]=mem3;
-   mem[4]=mem4;
 }
 
 
@@ -150,7 +143,7 @@
    int i;
    opus_val32 ac[5];
    opus_val16 tmp=Q15ONE;
-   opus_val16 lpc[4], mem[5]={0,0,0,0,0};
+   opus_val16 lpc[4];
    opus_val16 lpc2[5];
    opus_val16 c1 = QCONST16(.8f,15);
 #ifdef FIXED_POINT
@@ -211,7 +204,7 @@
    lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]);
    lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]);
    lpc2[4] = MULT16_16_Q15(c1,lpc[3]);
-   celt_fir5(x_lp, lpc2, x_lp, len>>1, mem);
+   celt_fir5(x_lp, lpc2, len>>1);
 }
 
 /* Pure C implementation. */
@@ -256,7 +249,7 @@
    opus_val32 maxcorr=1;
 #endif
    celt_assert(max_pitch>0);
-   celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
+   celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
    for (i=0;i<max_pitch-3;i+=4)
    {
       opus_val32 sum[4]={0,0,0,0};
diff --git a/celt/quant_bands.c b/celt/quant_bands.c
index 56101b1..39a221e 100644
--- a/celt/quant_bands.c
+++ b/celt/quant_bands.c
@@ -457,7 +457,7 @@
          /* It would be better to express this invariant as a
             test on C at function entry, but that isn't enough
             to make the static analyzer happy. */
-         celt_assert(c<2);
+         celt_sig_assert(c<2);
          tell = ec_tell(dec);
          if(budget-tell>=15)
          {
diff --git a/celt/rate.c b/celt/rate.c
index ca4cc87..465e1ba 100644
--- a/celt/rate.c
+++ b/celt/rate.c
@@ -529,7 +529,7 @@
    return codedBands;
 }
 
-int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
+int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
       opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)
 {
    int lo, hi, len, j;
diff --git a/celt/rate.h b/celt/rate.h
index 515f768..852b9d6 100644
--- a/celt/rate.h
+++ b/celt/rate.h
@@ -95,7 +95,7 @@
  @param pulses Number of pulses per band (returned)
  @return Total number of bits allocated
 */
-int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
+int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
       opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth);
 
 #endif
diff --git a/celt/tests/test_unit_entropy.c b/celt/tests/test_unit_entropy.c
index ff92658..7f67452 100644
--- a/celt/tests/test_unit_entropy.c
+++ b/celt/tests/test_unit_entropy.c
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <math.h>
 #include <time.h>
+#define CELT_C
 #include "entcode.h"
 #include "entenc.h"
 #include "entdec.h"
diff --git a/celt/tests/test_unit_laplace.c b/celt/tests/test_unit_laplace.c
index 22951e2..727bf01 100644
--- a/celt/tests/test_unit_laplace.c
+++ b/celt/tests/test_unit_laplace.c
@@ -31,8 +31,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "laplace.h"
 #define CELT_C
+#include "laplace.h"
 #include "stack_alloc.h"
 
 #include "entenc.c"
diff --git a/celt/tests/test_unit_rotation.c b/celt/tests/test_unit_rotation.c
index 267b983..8a31b3f 100644
--- a/celt/tests/test_unit_rotation.c
+++ b/celt/tests/test_unit_rotation.c
@@ -33,8 +33,6 @@
 #define CUSTOM_MODES
 #endif
 
-#define CELT_C
-
 #include <stdio.h>
 #include <stdlib.h>
 #include "vq.h"
diff --git a/celt/vq.c b/celt/vq.c
index 8ef80e5..a6b5552 100644
--- a/celt/vq.c
+++ b/celt/vq.c
@@ -230,12 +230,12 @@
          pulsesLeft -= iy[j];
       }  while (++j<N);
    }
-   celt_assert2(pulsesLeft>=0, "Allocated too many pulses in the quick pass");
+   celt_sig_assert(pulsesLeft>=0);
 
    /* This should never happen, but just in case it does (e.g. on silence)
       we fill the first bin with pulses. */
 #ifdef FIXED_POINT_DEBUG
-   celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass");
+   celt_sig_assert(pulsesLeft<=N+3);
 #endif
    if (pulsesLeft > N+3)
    {
diff --git a/celt/x86/celt_lpc_sse.c b/celt/x86/celt_lpc_sse4_1.c
similarity index 100%
rename from celt/x86/celt_lpc_sse.c
rename to celt/x86/celt_lpc_sse4_1.c
diff --git a/celt/x86/vq_sse2.c b/celt/x86/vq_sse2.c
index 6a31770..7750428 100644
--- a/celt/x86/vq_sse2.c
+++ b/celt/x86/vq_sse2.c
@@ -135,7 +135,7 @@
    }
    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");
+   celt_sig_assert(pulsesLeft>=0);
 
    /* This should never happen, but just in case it does (e.g. on silence)
       we fill the first bin with pulses. */
diff --git a/celt_sources.mk b/celt_sources.mk
index f7d81cc..b619dae 100644
--- a/celt_sources.mk
+++ b/celt_sources.mk
@@ -27,7 +27,7 @@
 celt/x86/vq_sse2.c
 
 CELT_SOURCES_SSE4_1 = \
-celt/x86/celt_lpc_sse.c \
+celt/x86/celt_lpc_sse4_1.c \
 celt/x86/pitch_sse4_1.c
 
 CELT_SOURCES_ARM = \
@@ -45,5 +45,5 @@
 celt/arm/pitch_neon_intr.c
 
 CELT_SOURCES_ARM_NE10 = \
-celt/arm/celt_ne10_fft.c \
-celt/arm/celt_ne10_mdct.c
+celt/arm/celt_fft_ne10.c \
+celt/arm/celt_mdct_ne10.c
diff --git a/configure.ac b/configure.ac
index 5ffa2d3..e2921fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,9 +22,9 @@
 
 # For libtool.
 dnl Please update these for releases.
-OPUS_LT_CURRENT=6
-OPUS_LT_REVISION=1
-OPUS_LT_AGE=6
+OPUS_LT_CURRENT=7
+OPUS_LT_REVISION=0
+OPUS_LT_AGE=7
 
 AC_SUBST(OPUS_LT_CURRENT)
 AC_SUBST(OPUS_LT_REVISION)
@@ -414,7 +414,7 @@
          NE10_CFLAGS="-I$NE10_includes"
       elif test "x$NE10_prefix" = "xno" || test "x$NE10_prefix" = "xyes" ; then
          NE10_CFLAGS=""
-      elif test "x$ogg_prefix" != "x" ; then
+      elif test "x$NE10_prefix" != "x" ; then
          NE10_CFLAGS="-I$NE10_prefix/include"
       elif test "x$prefix" != "xNONE"; then
          NE10_CFLAGS="-I$prefix/include"
@@ -759,8 +759,16 @@
   AC_DEFINE([ENABLE_ASSERTIONS], [1], [Assertions])
 ])
 
+AC_ARG_ENABLE([hardening],
+    [AS_HELP_STRING([--disable-hardening],[disable run-time checks that are cheap and safe for use in production])],,
+    [enable_hardening=yes])
+
+AS_IF([test "$enable_hardening" = "yes"], [
+  AC_DEFINE([ENABLE_HARDENING], [1], [Hardening])
+])
+
 AC_ARG_ENABLE([fuzzing],
-    [AS_HELP_STRING([--enable-fuzzing],[causes the encoder to make random decisions])],,
+	      [AS_HELP_STRING([--enable-fuzzing],[causes the encoder to make random decisions (do not use in production)])],,
     [enable_fuzzing=no])
 
 AS_IF([test "$enable_fuzzing" = "yes"], [
@@ -776,14 +784,6 @@
   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])
-
-AS_IF([test "$enable_ambisonics" = "yes"], [
-  AC_DEFINE([ENABLE_EXPERIMENTAL_AMBISONICS], [1], [Ambisonics Support])
-])
-
 AC_ARG_ENABLE([doc],
     [AS_HELP_STRING([--disable-doc], [Do not build API documentation])],,
     [enable_doc=yes])
@@ -804,12 +804,12 @@
 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])
+AC_ARG_ENABLE([rfc8251],
+	      AS_HELP_STRING([--disable-rfc8251], [Disable bitstream fixes from RFC 8251]),,
+  [enable_rfc8251=yes])
 
-AS_IF([test "$enable_update_draft" = "yes"], [
-  AC_DEFINE([ENABLE_UPDATE_DRAFT], [1], [Enable bitstream changes from draft-ietf-codec-opus-update])
+AS_IF([test "$enable_rfc8251" = "no"], [
+       AC_DEFINE([DISABLE_UPDATE_DRAFT], [1], [Disable bitstream fixes from RFC 8251])
 ])
 
 
@@ -822,6 +822,48 @@
       CFLAGS="$saved_CFLAGS"
     ])
 
+on_x86=no
+case "$host_cpu" in
+i[[3456]]86 | x86_64)
+  on_x86=yes
+  ;;
+esac
+
+on_windows=no
+case $host in
+*cygwin*|*mingw*)
+  on_windows=yes
+  ;;
+esac
+
+dnl Enable stack-protector-all only on x86 where it's well supported.
+dnl on some platforms it causes crashes. Hopefully the OS's default's
+dnl include this on platforms that work but have been missed here.
+AC_ARG_ENABLE([stack-protector],
+    [AS_HELP_STRING([--disable-stack-protector],[Disable compiler stack hardening])],,
+    [
+      AS_IF([test "$ac_cv_c_compiler_gnu" = "yes" && test "$on_x86" = "yes" && test "$on_windows" = "no"],
+            [enable_stack_protector=yes],[enable_stack_protector=no])
+    ])
+
+AS_IF([test "$enable_stack_protector" = "yes"],
+ [
+  saved_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fstack-protector-strong"
+  AC_MSG_CHECKING([if ${CC} supports -fstack-protector-strong])
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[[char foo;]])],
+    [ AC_MSG_RESULT([yes]) ],
+    [
+      AC_MSG_RESULT([no])
+      enable_stack_protector=no
+      CFLAGS="$saved_CFLAGS"
+    ])
+ ])
+
+AS_IF([test x$ac_cv_c_compiler_gnu = xyes],
+    [AX_ADD_FORTIFY_SOURCE]
+)
+
 CFLAGS="$CFLAGS -W"
 
 warn_CFLAGS="-Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes"
@@ -873,13 +915,13 @@
       Fixed point debugging: ......... ${enable_fixed_point_debug}
       Inline Assembly Optimizations: . ${inline_optimization}
       External Assembly Optimizations: ${asm_optimization}
-      Intrinsics Optimizations.......: ${intrinsics_support}
+      Intrinsics Optimizations: ...... ${intrinsics_support}
       Run-time CPU detection: ........ ${rtcd_support}
       Custom modes: .................. ${enable_custom_modes}
       Assertion checking: ............ ${enable_assertions}
+      Hardening: ..................... ${enable_hardening}
       Fuzzing: ....................... ${enable_fuzzing}
       Check ASM: ..................... ${enable_check_asm}
-      Ambisonics support: ............ ${enable_ambisonics}
 
       API documentation: ............. ${enable_doc}
       Extra programs: ................ ${enable_extra_programs}
diff --git a/doc/draft-ietf-codec-opus-update.xml b/doc/draft-ietf-codec-opus-update.xml
index a97124f..3124e22 100644
--- a/doc/draft-ietf-codec-opus-update.xml
+++ b/doc/draft-ietf-codec-opus-update.xml
@@ -10,8 +10,8 @@
 <?rfc inline="yes"?>
 <?rfc compact="yes"?>
 <?rfc subcompact="no"?>
-<rfc category="std" docName="draft-ietf-codec-opus-update-06"
-     ipr="trust200902">
+<rfc category="std" docName="draft-ietf-codec-opus-update-10"
+     ipr="trust200902" updates="6716">
   <front>
     <title abbrev="Opus Update">Updates to the Opus Audio Codec</title>
 
@@ -47,21 +47,26 @@
 
 
 
-    <date day="19" month="June" year="2017" />
+    <date day="24" month="August" year="2017" />
 
     <abstract>
       <t>This document addresses minor issues that were found in the specification
-      of the Opus audio codec in <xref target="RFC6716">RFC 6716</xref>.</t>
+      of the Opus audio codec in RFC 6716. It updates the normative decoder implementation
+      included in the appendix of RFC 6716. The changes fixes real and potential security-related
+      issues, as well minor quality-related issues.</t>
     </abstract>
   </front>
 
   <middle>
     <section title="Introduction">
       <t>This document addresses minor issues that were discovered in the reference
-      implementation of the Opus codec that serves as the specification in
-      <xref target="RFC6716">RFC 6716</xref>. Only issues affecting the decoder are
+      implementation of the Opus codec. Unlike most IETF specifications, Opus is defined
+      in <xref target="RFC6716">RFC 6716</xref> in terms of a normative reference
+      decoder implementation rather than from the associated text description.
+      That RFC includes the reference decoder implementation as Appendix A.
+      That's why only issues affecting the decoder are
       listed here. An up-to-date implementation of the Opus encoder can be found at
-      https://opus-codec.org/.</t>
+      <eref target="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
@@ -75,8 +80,8 @@
     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)
+    <eref target="https://www.ietf.org/proceedings/98/slides/materials-98-codec-opus-update-00.patch"/>
+    and has a SHA-1 hash of 029e3aa88fc342c91e67a21e7bfbc9458661cd5f.
     </t>
 
     </section>
@@ -96,6 +101,7 @@
     </t>
 <figure>
 <artwork><![CDATA[
+<CODE BEGINS>
      for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
          ret  = silk_init_decoder( &channel_state[ n ] );
      }
@@ -106,11 +112,12 @@
  
      return ret;
  }
+<CODE ENDS>
 ]]></artwork>
 </figure>
      <t>
-     This change affects the normative part of the decoder, although the
-     amount of change is too small to make a significant impact on testvectors.
+     This change affects the normative output of the decoder, but the
+     amount of change is within the tolerance and too small to make the testvector check fail.
       </t>
     </section>
 
@@ -118,11 +125,13 @@
       <t>It was discovered that some invalid packets of very large size could trigger
       an out-of-bounds read in the Opus packet parsing code responsible for padding.
       This is due to an integer overflow if the signaled padding exceeds 2^31-1 bytes
-      (the actual packet may be smaller). The code can be fixed by applying the following
-      changes at line 596 of src/opus_decoder.c:
+      (the actual packet may be smaller). The code can be fixed by decrementing the
+      (signed) len value, instead of incrementing a separate padding counter.
+      This is done by applying the following changes at line 596 of src/opus_decoder.c:
     </t>
 <figure>
 <artwork><![CDATA[
+<CODE BEGINS>
        /* Padding flag is bit 6 */
        if (ch&0x40)
        {
@@ -138,12 +147,13 @@
           } while (p==255);
 -         len -= padding;
        }
+<CODE ENDS>
 ]]></artwork>
 </figure>
       <t>This packet parsing issue is limited to reading memory up
          to about 60 kB beyond the compressed buffer. This can only be triggered
          by a compressed packet more than about 16 MB long, so it's not a problem
-         for RTP. In theory, it <spanx style="emph">could</spanx> crash a file
+         for RTP. In theory, it could crash a file
          decoder (e.g. Opus in Ogg) if the memory just after the incoming packet
          is out-of-range, but our attempts to trigger such a crash in a production
          application built using an affected version of the Opus decoder failed.</t>
@@ -155,25 +165,20 @@
     <t>The calls to memcpy() were using sizeof(opus_int32), but the type of the
         local buffer was opus_int16.</t>
     <t>Because the size was wrong, this potentially allowed the source
-        and destination regions of the memcpy() to overlap.
-          We <spanx style="emph">believe</spanx> that nSamplesIn is at least fs_in_khZ,
+        and destination regions of the memcpy() to overlap on the copy from "buf" to "buf".
+          We believe that nSamplesIn (number of input samples) is at least fs_in_khZ (sampling rate in kHz),
           which is at least 8.
        Since RESAMPLER_ORDER_FIR_12 is only 8, that should not be a problem once
        the type size is fixed.</t>
           <t>The size of the buffer used RESAMPLER_MAX_BATCH_SIZE_IN, but the
-        data stored in it was actually _twice_ the input batch size
+        data stored in it was actually twice the input batch size
         (nSamplesIn&lt;&lt;1).</t>
       </list></t>
-      <t>
-      The fact that the code never produced any error in testing (including when run under the
-      Valgrind memory debugger), suggests that in practice
-     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 78 of silk/resampler_private_IIR_FIR.c:
     </t>
 <figure>
 <artwork><![CDATA[
+<CODE BEGINS>
  )
  {
      silk_resampler_state_struct *S = \
@@ -226,6 +231,7 @@
 +    silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], \
 RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
  }
+<CODE ENDS>
 ]]></artwork>
 </figure>
     </section>
@@ -234,12 +240,13 @@
       <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
+        a wrap-around. The C standard considers
+        this behavior as undefined. 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>
 <figure>
 <artwork><![CDATA[
+<CODE BEGINS>
          /* Update AR coefficient */
          for( n = 0; n < k; n++ ) {
 -            tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( \
@@ -255,20 +262,22 @@
 +            }
 +            Anew_QA[ n ] = ( opus_int32 )tmp64;
          }
+<CODE ENDS>
 ]]></artwork>
 </figure>
     </section>
 
-    <section title="Integer wrap-around in LSF decoding">
+    <section title="Integer wrap-around in LSF decoding" anchor="lsf_overflow">
       <t>
         It was discovered -- also from decoder fuzzing -- that an integer wrap-around could
-        occur when decoding line spectral frequency coefficients from extreme bitstreams.
+        occur when decoding bitstreams with extremely large values for the high LSF parameters.
         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[
+<CODE BEGINS>
            /* Keep delta_min distance between the NLSFs */
          for( i = 1; i < L; i++ )
 -            NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], \
@@ -277,6 +286,7 @@
 silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
  
          /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
+<CODE ENDS>
 ]]></artwork>
 </figure>
 
@@ -285,12 +295,13 @@
     <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,
+        to a linear scale. This would later cause the decoded values to be NaN (not a number),
         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[
+<CODE BEGINS>
        {
           opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
                           SHL16((opus_val16)eMeans[i],6));
@@ -298,6 +309,7 @@
           eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
        }
        for (;i<m->nbEBands;i++)
+<CODE ENDS>
 ]]></artwork>
 </figure>
     </section>
@@ -307,7 +319,7 @@
         enough bits to code a single CELT band (8 - 9.6 kHz). When that happens,
         the second band (CELT band 18, from 9.6 to 12 kHz) cannot use folding
         because it is wider than the amount already coded, and falls back to
-        LCG noise. Because it can also happen on transients (e.g. stops), it
+        white noise. Because it can also happen on transients (e.g. stops), it
         can cause audible pre-echo.
       </t>
       <t>
@@ -319,6 +331,7 @@
       </t>
 <figure>
 <artwork><![CDATA[
+<CODE BEGINS>
           b = 0;
        }
  
@@ -347,6 +360,7 @@
        tf_change = tf_res[i];
        if (i>=m->effEBands)
        {
+<CODE ENDS>
 ]]></artwork>
 </figure>
 
@@ -356,6 +370,7 @@
 
 <figure>
 <artwork><![CDATA[
+<CODE BEGINS>
           fold_start = lowband_offset;
           while(M*eBands[--fold_start] > effective_lowband);
           fold_end = lowband_offset-1;
@@ -366,6 +381,7 @@
           fold_i = fold_start; do {
             x_cm |= collapse_masks[fold_i*C+0];
 
+<CODE ENDS>
 ]]></artwork>
 </figure>
       <t>
@@ -383,11 +399,11 @@
       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.
+      sometimes resulting in audible artifacts.
       </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).
+      phase shift. This can be useful when downmixing to mono inside or
+      outside of the decoder (e.g. user-controllable).
       </t>
     </section>
 
@@ -402,14 +418,72 @@
         implementation is compliant as long as it passes either set of vectors.
       </t>
       <t>
-        In addition, any Opus implementation
-        that passes the original test vectors from <xref target="RFC6716">RFC 6716</xref>
-        is still compliant with the Opus specification. However, newer implementations
+        Any Opus implementation
+        that passes either the original test vectors from <xref target="RFC6716">RFC 6716</xref>
+        or one of the new sets of test vectors is compliant with the Opus specification. However, newer implementations
         SHOULD be based on the new test vectors rather than the old ones.
       </t>
       <t>The new test vectors are located at
-        <eref target="https://jmvalin.ca/misc_stuff/opus_newvectors.tar.gz"/>. (EDITOR:
-        change to an ietf.org link when ready)
+        <eref target="https://www.ietf.org/proceedings/98/slides/materials-98-codec-opus-newvectors-00.tar.gz"/>.
+        The SHA-1 hashes of the test vectors are:
+<figure>
+<artwork>
+<![CDATA[
+e49b2862ceec7324790ed8019eb9744596d5be01  testvector01.bit
+b809795ae1bcd606049d76de4ad24236257135e0  testvector02.bit
+e0c4ecaeab44d35a2f5b6575cd996848e5ee2acc  testvector03.bit
+a0f870cbe14ebb71fa9066ef3ee96e59c9a75187  testvector04.bit
+9b3d92b48b965dfe9edf7b8a85edd4309f8cf7c8  testvector05.bit
+28e66769ab17e17f72875283c14b19690cbc4e57  testvector06.bit
+bacf467be3215fc7ec288f29e2477de1192947a6  testvector07.bit
+ddbe08b688bbf934071f3893cd0030ce48dba12f  testvector08.bit
+3932d9d61944dab1201645b8eeaad595d5705ecb  testvector09.bit
+521eb2a1e0cc9c31b8b740673307c2d3b10c1900  testvector10.bit
+6bc8f3146fcb96450c901b16c3d464ccdf4d5d96  testvector11.bit
+338c3f1b4b97226bc60bc41038becbc6de06b28f  testvector12.bit
+f5ef93884da6a814d311027918e9afc6f2e5c2c8  testvector01.dec
+48ac1ff1995250a756e1e17bd32acefa8cd2b820  testvector02.dec
+d15567e919db2d0e818727092c0af8dd9df23c95  testvector03.dec
+1249dd28f5bd1e39a66fd6d99449dca7a8316342  testvector04.dec
+b85675d81deef84a112c466cdff3b7aaa1d2fc76  testvector05.dec
+55f0b191e90bfa6f98b50d01a64b44255cb4813e  testvector06.dec
+61e8b357ab090b1801eeb578a28a6ae935e25b7b  testvector07.dec
+a58539ee5321453b2ddf4c0f2500e856b3966862  testvector08.dec
+bb96aad2cde188555862b7bbb3af6133851ef8f4  testvector09.dec
+1b6cdf0413ac9965b16184b1bea129b5c0b2a37a  testvector10.dec
+b1fff72b74666e3027801b29dbc48b31f80dee0d  testvector11.dec
+98e09bbafed329e341c3b4052e9c4ba5fc83f9b1  testvector12.dec
+1e7d984ea3fbb16ba998aea761f4893fbdb30157  testvector01m.dec
+48ac1ff1995250a756e1e17bd32acefa8cd2b820  testvector02m.dec
+d15567e919db2d0e818727092c0af8dd9df23c95  testvector03m.dec
+1249dd28f5bd1e39a66fd6d99449dca7a8316342  testvector04m.dec
+d70b0bad431e7d463bc3da49bd2d49f1c6d0a530  testvector05m.dec
+6ac1648c3174c95fada565161a6c78bdbe59c77d  testvector06m.dec
+fc5e2f709693738324fb4c8bdc0dad6dda04e713  testvector07m.dec
+aad2ba397bf1b6a18e8e09b50e4b19627d479f00  testvector08m.dec
+6feb7a7b9d7cdc1383baf8d5739e2a514bd0ba08  testvector09m.dec
+1b6cdf0413ac9965b16184b1bea129b5c0b2a37a  testvector10m.dec
+fd3d3a7b0dfbdab98d37ed9aa04b659b9fefbd18  testvector11m.dec
+98e09bbafed329e341c3b4052e9c4ba5fc83f9b1  testvector12m.dec
+]]>
+</artwork>
+</figure>
+      Note that the decoder input bitstream files (.bit) are unchanged.
+      </t>
+    </section>
+
+    <section anchor="security" title="Security Considerations">
+      <t>This document fixes two security issues reported on Opus and that affect the
+        reference implementation in <xref target="RFC6716">RFC 6716</xref>: CVE-2013-0899
+        <eref target="https://nvd.nist.gov/vuln/detail/CVE-2013-0899"/>
+        and CVE-2017-0381 <eref target="https://nvd.nist.gov/vuln/detail/CVE-2017-0381"/>.
+        CVE- 2013-0899 theoretically could have caused an information leak. The leaked
+        information would have gone through the decoder process before being accessible
+        to the attacker. It is fixed by <xref target="padding"/>.
+        CVE-2017-0381 could have resulted in a 16-bit out-of-bounds read from a fixed
+        location.  It is fixed in <xref target="lsf_overflow"/>.
+        Beyond the two fixed CVEs, this document adds no new security considerations on top of
+        <xref target="RFC6716">RFC 6716</xref>.
       </t>
     </section>
 
@@ -422,13 +496,14 @@
 
     <section anchor="Acknowledgements" title="Acknowledgements">
       <t>We would like to thank Juri Aedla for reporting the issue with the parsing of
-      the Opus padding. Also, thanks to Jonathan Lennox and Mark Harris for their
+      the Opus padding. Thanks to Felicia Lim for reporting the LSF integer overflow issue.
+      Also, thanks to Tina le Grand, Jonathan Lennox, and Mark Harris for their
       feedback on this document.</t>
     </section>
   </middle>
 
   <back>
-    <references title="References">
+    <references title="Normative References">
       <?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"?>
       <?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.6716.xml"?>
 
diff --git a/doc/opus_in_isobmff.html b/doc/opus_in_isobmff.html
index a1175db..38aefbf 100644
--- a/doc/opus_in_isobmff.html
+++ b/doc/opus_in_isobmff.html
@@ -7,12 +7,12 @@
     </head>
     <body bgcolor="0x333333" text="#60B0C0">
         <b><u>Encapsulation of Opus in ISO Base Media File Format</u></b><br>
-        <font size="2">last updated: April 28, 2016</font><br>
+        <font size="2">last updated: August 28, 2018</font><br>
         <br>
         <div class="normal_link pre frame_box">
 
                                 Encapsulation of Opus in ISO Base Media File Format
-                                        Version 0.6.8 (incomplete)
+                                        Version 0.8.1 (incomplete)
 
 
 Table of Contents
@@ -20,7 +20,7 @@
 <a href="#2">2</a> Normative References
 <a href="#3">3</a> Terms and Definitions
 <a href="#4">4</a> Design Rules of Encapsulation
-    <a href="#4.1">4.1</a> File Type Indentification
+    <a href="#4.1">4.1</a> File Type Identification
     <a href="#4.2">4.2</a> Overview of Track Structure
     <a href="#4.3">4.3</a> Definitions of Opus sample
         <a href="#4.3.1">4.3.1</a> Sample entry format
@@ -32,7 +32,9 @@
             <a href="#4.3.6.1">4.3.6.1</a> Random Access Point
             <a href="#4.3.6.2">4.3.6.2</a> Pre-roll
     <a href="#4.4">4.4</a> Trimming of Actual Duration
-    <a href="#4.5">4.5</a> Channel Layout (informative)
+    <a href="#4.5">4.5</a> Channel Mapping
+        <a href="#4.5.1">4.5.1</a> ISO Base Media native Channel Mapping
+        <a href="#4.5.2">4.5.2</a> Composition on all active tracks (informative)
     <a href="#4.6">4.6</a> Basic Structure (informative)
         <a href="#4.6.1">4.6.2</a> Initial Movie
         <a href="#4.6.2">4.6.3</a> Movie Fragments
@@ -53,7 +55,7 @@
     [2] RFC 6716
         Definition of the Opus Audio Codec
 
-    [3] draft-ietf-codec-oggopus-06
+    [3] RFC 7845
         Ogg Encapsulation for the Opus Audio Codec
 
 <a name="3"></a>
@@ -83,8 +85,8 @@
 
 <a name="4"></a>
 4 Design Rules of Encapsulation
-    4.1 File Type Indentification<a name="4.1"></a>
-        This specification does not define any brand to declare files are conformant to this specification. However,
+    4.1 File Type Identification<a name="4.1"></a>
+        This specification defines the brand 'Opus' to declare files are conformant to this specification. Additionally,
         files conformant to this specification shall contain at least one brand, which supports the requirements and the
         requirements described in this clause without contradiction, in the compatible brands list of the File Type Box.
         As an example, the minimal support of the encapsulation of Opus bitstreams in ISO Base Media file format requires
@@ -117,15 +119,14 @@
 
             The syntax and semantics of the OpusSampleEntry is shown as follows.
 
-            class OpusSampleEntry() extends AudioSampleEntry ('Opus'){
+            class OpusSampleEntry() extends AudioSampleEntry ('Opus') {
                 OpusSpecificBox();
             }
 
             + channelcount:
-                The channelcount field shall be set to the sum of the total number of Opus bitstreams and the number
-                of Opus bitstreams producing two channels. This value is indentical with (M+N), where M is the value of
-                the *Coupled Stream Count* field and N is the value of the *Stream Count* field in the *Channel Mapping
-                Table* in the identification header defined in Ogg Opus [3].
+                The channelcount field indicates the number of output channels and shall be set to the same value of
+                the OutputChannelCount in the OpusDecoderConfigurationRecord. The value of this field may be used in
+                the ChannelLayout if any as described in 4.5.1.
             + samplesize:
                 The samplesize field shall be set to 16.
             + samplerate:
@@ -135,20 +136,21 @@
 
         4.3.2 Opus Specific Box<a name="4.3.2"></a>
             Exactly one Opus Specific Box shall be present in each OpusSampleEntry.
-            The Opus Specific Box contains the Version field and this specification defines version 0 of this box.
-            If incompatible changes occured in the fields after the Version field within the OpusSpecificBox in the
-            future versions of this specification, another version will be defined.
+            The Opus Specific Box contains an OpusDecoderConfigurationRecord which contains the Version field and
+            this specification defines version 0 of this record. If incompatible changes occured in the fields after
+            the Version field within the OpusDecoderConfigurationRecord in the future versions of this specification,
+            another version will be defined.
             This box refers to Ogg Opus [3] at many parts but all the data are stored as big-endian format.
 
             The syntax and semantics of the Opus Specific Box is shown as follows.
 
-            class ChannelMappingTable (unsigned int(8) OutputChannelCount){
+            class ChannelMappingTable (unsigned int(8) OutputChannelCount) {
                 unsigned int(8) StreamCount;
                 unsigned int(8) CoupledCount;
                 unsigned int(8 * OutputChannelCount) ChannelMapping;
             }
 
-            aligned(8) class OpusSpecificBox extends Box('dOps'){
+            aligned(8) class OpusDecoderConfigurationRecord {
                 unsigned int(8) Version;
                 unsigned int(8) OutputChannelCount;
                 unsigned int(16) PreSkip;
@@ -160,6 +162,10 @@
                 }
             }
 
+            class OpusSpecificBox extends Box('dOps') {
+                OpusDecoderConfigurationRecord() OpusConfig;
+            }
+
             + Version:
                 The Version field shall be set to 0.
                 In the future versions of this specification, this field may be set to other values. And without support
@@ -181,7 +187,8 @@
                 header define in Ogg Opus [3]. Note that the value is stored as 8.8 fixed-point.
             + ChannelMappingFamily:
                 The ChannelMappingFamily field shall be set to the same value as the *Channel Mapping Family* field in
-                the identification header defined in Ogg Opus [3].
+                the identification header defined in Ogg Opus [3]. Note that the value 255 may be used for an alternative
+                to map channels by ISO Base Media native mapping. The details are described in 4.5.1.
             + StreamCount:
                 The StreamCount field shall be set to the same value as the *Stream Count* field in the identification
                 header defined in Ogg Opus [3].
@@ -270,42 +277,62 @@
         the duration of the last Opus sample may be helpful by setting zero to the segment_duration field since the
         value 0 represents implicit duration equal to the sum of the duration of all samples.
 <a name="4.5"></a>
-    4.5 Channel Layout (informative)
-        By the application of alternate_group in the Track Header Box, whole audio channels in all active tracks from
-        non-alternate group and/or different alternate group from each other are composited into the presentation. If
-        an Opus sample consists of multiple Opus bitstreams, it can be splitted into individual Opus bitstreams and
-        reconstructed into new Opus samples as long as every Opus bitstream has the same total duration in each Opus
-        sample. This nature can be utilized to encapsulate a single Opus bitstream in each track without breaking the
-        original channel layout.
+    4.5 Channel Mapping
+        4.5.1 ISO Base Media native Channel Mapping<a name="4.5.1"></a>
+            ISO Base Media File Format, that is ISO/IEC 14496-12 [1], defines an extension ChannelLayout to the
+            AudioSampleEntry, which conveys information of mapping channels to loudspeaker positions. The ChannelLayout
+            enables to specify the channel layout more flexibly than the predefined layouts of the ChannelMappingFamily.
 
-        As an example, let's say there is a following track:
-            OutputChannelCount = 6;
-            StreamCount        = 4;
-            CoupledCount       = 2;
-            ChannelMapping     = {0, 4, 1, 2, 3, 5}; // front left, front center, front right, rear left, rear right, LFE
-        Here, to couple front left to front right channels into the first stream, and couple rear left to rear right
-        channels into the second stream, reordering is needed since coupled streams must precede any non-coupled stream.
-        You extract the four Opus bitstreams from this track and you encapsulate two of the four into a track and the
-        others into another track. The former track is as follows.
-            OutputChannelCount = 6;
-            StreamCount        = 2;
-            CoupledCount       = 2;
-            ChannelMapping     = {0, 255, 1, 2, 3, 255}; // front left, front center, front right, rear left, rear right, LFE
-        And the latter track is as follows.
-            OutputChannelCount = 6;
-            StreamCount        = 2;
-            CoupledCount       = 0;
-            ChannelMapping     = {255, 0, 255, 255, 255, 1}; // front left, front center, front right, rear left, rear right, LFE
-        In addition, the value of the alternate_group field in the both tracks is set to 0. As the result, the player
-        may play as if channels with 255 are not present, and play the presentation constructed from the both tracks
-        in the same channel layout as the one of the original track. Keep in mind that the way of the composition, i.e.
-        the mixing for playback, is not defined here, and maybe different results could occur except for the channel
-        layout of the original, depending on an implementation or the definition of a derived file format.
+            To utilize the ChannelLayout for OpusSampleEntry, the ChannelMappingFamily field should be set to 255.
+            Even when the ChannelMappingFamily field is set to another value, the assignment of each output channel to
+            loudspeaker position specified by the ChannelMappingFamily would be changed as specified by the ChannelLayout.
+            The procedure of the assignment is the following.
 
-        Note that some derived file formats may specify the restriction to ignore alternate grouping. In the context of
-        such file formats, this application is not available. This unavailability does not mean incompatibilities among
-        file formats unless the restriction to the value of the alternate_group field is specified and brings about
-        any conflict among their definitions.
+                1. Decoded channels are mapped to output channels according to the ChannelMappingTable.
+                2. Output channels are mapped to loudspeaker positions according to the ChannelLayout.
+
+            In this way, the parameters of the Opus Specific Box are processed before the ChannelLayout, and the
+            ChannelLayout shall follow the Opus Specific Box.
+
+        4.5.2 Composition on all active tracks (informative)<a name="4.5.2"></a>
+            By the application of alternate_group in the Track Header Box, whole audio channels in all active tracks from
+            non-alternate group and/or different alternate group from each other are composited into the presentation. If
+            an Opus sample consists of multiple Opus bitstreams, it can be splitted into individual Opus bitstreams and
+            reconstructed into new Opus samples as long as every Opus bitstream has the same total duration in each Opus
+            sample. This nature can be utilized to encapsulate a single Opus bitstream in each track without breaking the
+            original channel layout.
+
+            As an example, let's say there is a following track:
+                OutputChannelCount = 6;
+                StreamCount        = 4;
+                CoupledCount       = 2;
+                ChannelMapping     = {0, 4, 1, 2, 3, 5}; // front left, front center, front right,
+                                                         // rear left, rear right, LFE
+            Here, to couple front left to front right channels into the first stream, and couple rear left to rear right
+            channels into the second stream, reordering is needed since coupled streams must precede any non-coupled
+            stream. You extract the four Opus bitstreams from this track and you encapsulate two of the four into a track
+            and the others into another track. The former track is as follows.
+                OutputChannelCount = 6;
+                StreamCount        = 2;
+                CoupledCount       = 2;
+                ChannelMapping     = {0, 255, 1, 2, 3, 255}; // front left, front center, front right,
+                                                             // rear left, rear right, LFE
+            And the latter track is as follows.
+                OutputChannelCount = 6;
+                StreamCount        = 2;
+                CoupledCount       = 0;
+                ChannelMapping     = {255, 0, 255, 255, 255, 1}; // front left, front center, front right,
+                                                                 // rear left, rear right, LFE
+            In addition, the value of the alternate_group field in the both tracks is set to 0. As the result, the player
+            may play as if channels with 255 are not present, and play the presentation constructed from the both tracks
+            in the same channel layout as the one of the original track. Keep in mind that the way of the composition, i.e.
+            the mixing for playback, is not defined here, and maybe different results could occur except for the channel
+            layout of the original, depending on an implementation or the definition of a derived file format.
+
+            Note that some derived file formats may specify the restriction to ignore alternate grouping. In the context
+            of such file formats, this application is not available. This unavailability does not mean incompatibilities
+            among file formats unless the restriction to the value of the alternate_group field is specified and brings
+            about any conflict among their definitions.
 <a name="4.6"></a>
     4.6 Basic Structure (informative)
         4.6.1 Initial Movie<a name="4.6.1"></a>
@@ -395,7 +422,7 @@
             +----+----+----+----+----+----+----+----+------------------------------+
             |    |    |sgpd|*   |    |    |    |    | Sample Group Description Box |
             +----+----+----+----+----+----+----+----+------------------------------+
-            |    |    |sbgp|*   |    |    |    |    | Sample to Group Box          |
+            |    |    |sbgp|    |    |    |    |    | Sample to Group Box          |
             +----+----+----+----+----+----+----+----+------------------------------+
 
                     Figure 3 - Basic structure of Movie Fragment Box
@@ -407,14 +434,14 @@
 <a name="4.7"></a>
     4.7 Example of Encapsulation (informative)
         [File]
-            size = 17790
+            size = 17757
             [ftyp: File Type Box]
                 position = 0
                 size = 24
-                major_brand = mp42 : MP4 version 2
+                major_brand = Opus : Opus audio coding
                 minor_version = 0
                 compatible_brands
-                    brand[0] = mp42 : MP4 version 2
+                    brand[0] = Opus : Opus audio coding
                     brand[1] = iso2 : ISO Base Media file format version 2
             [moov: Movie Box]
                 position = 24
@@ -444,30 +471,11 @@
                     pre_defined = 0x00000000
                     pre_defined = 0x00000000
                     next_track_ID = 2
-                [iods: Object Descriptor Box]
-                    position = 140
-                    size = 33
-                    version = 0
-                    flags = 0x000000
-                    [tag = 0x10: MP4_IOD]
-                        expandableClassSize = 16
-                        ObjectDescriptorID = 1
-                        URL_Flag = 0
-                        includeInlineProfileLevelFlag = 0
-                        reserved = 0xf
-                        ODProfileLevelIndication = 0xff
-                        sceneProfileLevelIndication = 0xff
-                        audioProfileLevelIndication = 0xfe
-                        visualProfileLevelIndication = 0xff
-                        graphicsProfileLevelIndication = 0xff
-                        [tag = 0x0e: ES_ID_Inc]
-                            expandableClassSize = 4
-                            Track_ID = 1
                 [trak: Track Box]
-                    position = 173
+                    position = 140
                     size = 608
                     [tkhd: Track Header Box]
-                        position = 181
+                        position = 148
                         size = 92
                         version = 0
                         flags = 0x000007
@@ -492,7 +500,7 @@
                         width = 0.000000
                         height = 0.000000
                     [edts: Edit Box]
-                        position = 273
+                        position = 240
                         size = 36
                         [elst: Edit List Box]
                             position = 281
@@ -505,10 +513,10 @@
                                 media_time = 312
                                 media_rate = 1.000000
                     [mdia: Media Box]
-                        position = 309
+                        position = 276
                         size = 472
                         [mdhd: Media Header Box]
-                            position = 317
+                            position = 284
                             size = 32
                             version = 0
                             flags = 0x000000
@@ -519,7 +527,7 @@
                             language = und
                             pre_defined = 0x0000
                         [hdlr: Handler Reference Box]
-                            position = 349
+                            position = 316
                             size = 51
                             version = 0
                             flags = 0x000000
@@ -530,41 +538,41 @@
                             reserved = 0x00000000
                             name = Xiph Audio Handler
                         [minf: Media Information Box]
-                            position = 400
+                            position = 367
                             size = 381
                             [smhd: Sound Media Header Box]
-                                position = 408
+                                position = 375
                                 size = 16
                                 version = 0
                                 flags = 0x000000
                                 balance = 0.000000
                                 reserved = 0x0000
                             [dinf: Data Information Box]
-                                position = 424
+                                position = 391
                                 size = 36
                                 [dref: Data Reference Box]
-                                    position = 432
+                                    position = 399
                                     size = 28
                                     version = 0
                                     flags = 0x000000
                                     entry_count = 1
                                     [url : Data Entry Url Box]
-                                        position = 448
+                                        position = 415
                                         size = 12
                                         version = 0
                                         flags = 0x000001
                                         location = in the same file
                             [stbl: Sample Table Box]
-                                position = 460
+                                position = 427
                                 size = 321
                                 [stsd: Sample Description Box]
-                                    position = 468
+                                    position = 435
                                     size = 79
                                     version = 0
                                     flags = 0x000000
                                     entry_count = 1
                                     [Opus: Audio Description]
-                                        position = 484
+                                        position = 451
                                         size = 63
                                         reserved = 0x000000000000
                                         data_reference_index = 1
@@ -577,7 +585,7 @@
                                         reserved = 0
                                         samplerate = 48000.000000
                                         [dOps: Opus Specific Box]
-                                            position = 520
+                                            position = 487
                                             size = 27
                                             Version = 0
                                             OutputChannelCount = 6
@@ -595,7 +603,7 @@
                                                 4 -> 3: side right
                                                 5 -> 5: rear center
                                 [stts: Decoding Time to Sample Box]
-                                    position = 547
+                                    position = 514
                                     size = 24
                                     version = 0
                                     flags = 0x000000
@@ -604,7 +612,7 @@
                                         sample_count = 18
                                         sample_delta = 1920
                                 [stsc: Sample To Chunk Box]
-                                    position = 571
+                                    position = 538
                                     size = 40
                                     version = 0
                                     flags = 0x000000
@@ -618,7 +626,7 @@
                                         samples_per_chunk = 5
                                         sample_description_index = 1
                                 [stsz: Sample Size Box]
-                                    position = 611
+                                    position = 578
                                     size = 92
                                     version = 0
                                     flags = 0x000000
@@ -643,7 +651,7 @@
                                     entry_size[16] = 962
                                     entry_size[17] = 848
                                 [stco: Chunk Offset Box]
-                                    position = 703
+                                    position = 670
                                     size = 24
                                     version = 0
                                     flags = 0x000000
@@ -651,7 +659,7 @@
                                     chunk_offset[0] = 797
                                     chunk_offset[1] = 13096
                                 [sgpd: Sample Group Description Box]
-                                    position = 727
+                                    position = 694
                                     size = 26
                                     version = 1
                                     flags = 0x000000
@@ -660,7 +668,7 @@
                                     entry_count = 1
                                     roll_distance[0] = -2
                                 [sbgp: Sample to Group Box]
-                                    position = 753
+                                    position = 720
                                     size = 28
                                     version = 0
                                     flags = 0x000000
@@ -670,10 +678,10 @@
                                         sample_count = 18
                                         group_description_index = 1
             [free: Free Space Box]
-                position = 781
+                position = 748
                 size = 8
             [mdat: Media Data Box]
-                position = 789
+                position = 756
                 size = 17001
 <a name="5"></a>
 5 Authors' Address
diff --git a/include/opus.h b/include/opus.h
index 5be73dd..d282f21 100644
--- a/include/opus.h
+++ b/include/opus.h
@@ -531,7 +531,7 @@
    const unsigned char *frames[48],
    opus_int16 size[48],
    int *payload_offset
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5);
 
 /** Gets the bandwidth of an Opus packet.
   * @param [in] data <tt>char*</tt>: Opus packet
diff --git a/include/opus_defines.h b/include/opus_defines.h
index 33c5acd..fbf5d0e 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -169,6 +169,9 @@
 #define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
 #define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
 
+/** Defines for the presence of extended APIs. */
+#define OPUS_HAVE_OPUS_PROJECTION_H
+
 /* Macros to trigger compilation errors when the wrong types are provided to a CTL */
 #define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
 #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
diff --git a/include/opus_projection.h b/include/opus_projection.h
new file mode 100644
index 0000000..9dabf4e
--- /dev/null
+++ b/include/opus_projection.h
@@ -0,0 +1,568 @@
+/* Copyright (c) 2017 Google Inc.
+   Written by Andrew Allen */
+/*
+   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.
+*/
+
+/**
+ * @file opus_projection.h
+ * @brief Opus projection reference API
+ */
+
+#ifndef OPUS_PROJECTION_H
+#define OPUS_PROJECTION_H
+
+#include "opus_multistream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @cond OPUS_INTERNAL_DOC */
+
+/** These are the actual encoder and decoder CTL ID numbers.
+  * They should not be used directly by applications.c
+  * In general, SETs should be even and GETs should be odd.*/
+/**@{*/
+#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST    6001
+#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST    6003
+#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST         6005
+/**@}*/
+
+
+/** @endcond */
+
+/** @defgroup opus_projection_ctls Projection specific encoder and decoder CTLs
+  *
+  * These are convenience macros that are specific to the
+  * opus_projection_encoder_ctl() and opus_projection_decoder_ctl()
+  * interface.
+  * The CTLs from @ref opus_genericctls, @ref opus_encoderctls,
+  * @ref opus_decoderctls, and @ref opus_multistream_ctls may be applied to a
+  * projection encoder or decoder as well.
+  */
+/**@{*/
+
+/** Gets the gain (in dB. S7.8-format) of the demixing matrix from the encoder.
+  * @param[out] x <tt>opus_int32 *</tt>: Returns the gain (in dB. S7.8-format)
+  *                                      of the demixing matrix.
+  * @hideinitializer
+  */
+#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, __opus_check_int_ptr(x)
+
+
+/** Gets the size in bytes of the demixing matrix from the encoder.
+  * @param[out] x <tt>opus_int32 *</tt>: Returns the size in bytes of the
+  *                                      demixing matrix.
+  * @hideinitializer
+  */
+#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, __opus_check_int_ptr(x)
+
+
+/** Copies the demixing matrix to the supplied pointer location.
+  * @param[out] x <tt>unsigned char *</tt>: Returns the demixing matrix to the
+  *                                         supplied pointer location.
+  * @param y <tt>opus_int32</tt>: The size in bytes of the reserved memory at the
+  *                              pointer location.
+  * @hideinitializer
+  */
+#define OPUS_PROJECTION_GET_DEMIXING_MATRIX(x,y) OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, x, __opus_check_int(y)
+
+
+/**@}*/
+
+/** Opus projection encoder state.
+ * This contains the complete state of a projection Opus encoder.
+ * It is position independent and can be freely copied.
+ * @see opus_projection_ambisonics_encoder_create
+ */
+typedef struct OpusProjectionEncoder OpusProjectionEncoder;
+
+
+/** Opus projection decoder state.
+  * This contains the complete state of a projection Opus decoder.
+  * It is position independent and can be freely copied.
+  * @see opus_projection_decoder_create
+  * @see opus_projection_decoder_init
+  */
+typedef struct OpusProjectionDecoder OpusProjectionDecoder;
+
+
+/**\name Projection encoder functions */
+/**@{*/
+
+/** Gets the size of an OpusProjectionEncoder structure.
+  * @param channels <tt>int</tt>: The total number of input channels to encode.
+  *                               This must be no more than 255.
+  * @param mapping_family <tt>int</tt>: The mapping family to use for selecting
+  *                                     the appropriate projection.
+  * @returns The size in bytes on success, or a negative error code
+  *          (see @ref opus_errorcodes) on error.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_ambisonics_encoder_get_size(
+    int channels,
+    int mapping_family
+);
+
+
+/** Allocates and initializes a projection encoder state.
+  * Call opus_projection_encoder_destroy() to release
+  * this object when finished.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels in the input signal.
+  *                               This must be at most 255.
+  *                               It may be greater than the number of
+  *                               coded channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param mapping_family <tt>int</tt>: The mapping family to use for selecting
+  *                                     the appropriate projection.
+  * @param[out] streams <tt>int *</tt>: The total number of streams that will
+  *                                     be encoded from the input.
+  * @param[out] coupled_streams <tt>int *</tt>: Number of coupled (2 channel)
+  *                                 streams that will be encoded from the input.
+  * @param application <tt>int</tt>: The target encoder application.
+  *                                  This must be one of the following:
+  * <dl>
+  * <dt>#OPUS_APPLICATION_VOIP</dt>
+  * <dd>Process signal for improved speech intelligibility.</dd>
+  * <dt>#OPUS_APPLICATION_AUDIO</dt>
+  * <dd>Favor faithfulness to the original input.</dd>
+  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+  * <dd>Configure the minimum possible coding delay by disabling certain modes
+  * of operation.</dd>
+  * </dl>
+  * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
+  *                                   code (see @ref opus_errorcodes) on
+  *                                   failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
+    opus_int32 Fs,
+    int channels,
+    int mapping_family,
+    int *streams,
+    int *coupled_streams,
+    int application,
+    int *error
+) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5);
+
+
+/** Initialize a previously allocated projection encoder state.
+  * The memory pointed to by \a st must be at least the size returned by
+  * opus_projection_ambisonics_encoder_get_size().
+  * This is intended for applications which use their own allocator instead of
+  * malloc.
+  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+  * @see opus_projection_ambisonics_encoder_create
+  * @see opus_projection_ambisonics_encoder_get_size
+  * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state to initialize.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels in the input signal.
+  *                               This must be at most 255.
+  *                               It may be greater than the number of
+  *                               coded channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams to encode from the
+  *                              input.
+  *                              This must be no more than the number of channels.
+  * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
+  *                                      to encode.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      encoded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than the number of input channels.
+  * @param application <tt>int</tt>: The target encoder application.
+  *                                  This must be one of the following:
+  * <dl>
+  * <dt>#OPUS_APPLICATION_VOIP</dt>
+  * <dd>Process signal for improved speech intelligibility.</dd>
+  * <dt>#OPUS_APPLICATION_AUDIO</dt>
+  * <dd>Favor faithfulness to the original input.</dd>
+  * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
+  * <dd>Configure the minimum possible coding delay by disabling certain modes
+  * of operation.</dd>
+  * </dl>
+  * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+  *          on failure.
+  */
+OPUS_EXPORT int opus_projection_ambisonics_encoder_init(
+    OpusProjectionEncoder *st,
+    opus_int32 Fs,
+    int channels,
+    int mapping_family,
+    int *streams,
+    int *coupled_streams,
+    int application
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
+
+
+/** Encodes a projection Opus frame.
+  * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
+  * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
+  *                                            samples.
+  *                                            This must contain
+  *                                            <code>frame_size*channels</code>
+  *                                            samples.
+  * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+  *                                 signal.
+  *                                 This must be an Opus frame size for the
+  *                                 encoder's sampling rate.
+  *                                 For example, at 48 kHz the permitted values
+  *                                 are 120, 240, 480, 960, 1920, and 2880.
+  *                                 Passing in a duration of less than 10 ms
+  *                                 (480 samples at 48 kHz) will prevent the
+  *                                 encoder from using the LPC or hybrid modes.
+  * @param[out] data <tt>unsigned char*</tt>: Output payload.
+  *                                           This must contain storage for at
+  *                                           least \a max_data_bytes.
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+  *                                                 memory for the output
+  *                                                 payload. This may be
+  *                                                 used to impose an upper limit on
+  *                                                 the instant bitrate, but should
+  *                                                 not be used as the only bitrate
+  *                                                 control. Use #OPUS_SET_BITRATE to
+  *                                                 control the bitrate.
+  * @returns The length of the encoded packet (in bytes) on success or a
+  *          negative error code (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode(
+    OpusProjectionEncoder *st,
+    const opus_int16 *pcm,
+    int frame_size,
+    unsigned char *data,
+    opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+
+/** Encodes a projection Opus frame from floating point input.
+  * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
+  * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
+  *                                       samples with a normal range of
+  *                                       +/-1.0.
+  *                                       Samples with a range beyond +/-1.0
+  *                                       are supported but will be clipped by
+  *                                       decoders using the integer API and
+  *                                       should only be used if it is known
+  *                                       that the far end supports extended
+  *                                       dynamic range.
+  *                                       This must contain
+  *                                       <code>frame_size*channels</code>
+  *                                       samples.
+  * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+  *                                 signal.
+  *                                 This must be an Opus frame size for the
+  *                                 encoder's sampling rate.
+  *                                 For example, at 48 kHz the permitted values
+  *                                 are 120, 240, 480, 960, 1920, and 2880.
+  *                                 Passing in a duration of less than 10 ms
+  *                                 (480 samples at 48 kHz) will prevent the
+  *                                 encoder from using the LPC or hybrid modes.
+  * @param[out] data <tt>unsigned char*</tt>: Output payload.
+  *                                           This must contain storage for at
+  *                                           least \a max_data_bytes.
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+  *                                                 memory for the output
+  *                                                 payload. This may be
+  *                                                 used to impose an upper limit on
+  *                                                 the instant bitrate, but should
+  *                                                 not be used as the only bitrate
+  *                                                 control. Use #OPUS_SET_BITRATE to
+  *                                                 control the bitrate.
+  * @returns The length of the encoded packet (in bytes) on success or a
+  *          negative error code (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode_float(
+    OpusProjectionEncoder *st,
+    const float *pcm,
+    int frame_size,
+    unsigned char *data,
+    opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
+
+/** Frees an <code>OpusProjectionEncoder</code> allocated by
+  * opus_projection_ambisonics_encoder_create().
+  * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state to be freed.
+  */
+OPUS_EXPORT void opus_projection_encoder_destroy(OpusProjectionEncoder *st);
+
+
+/** Perform a CTL function on a projection Opus encoder.
+  *
+  * Generally the request and subsequent arguments are generated by a
+  * convenience macro.
+  * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
+  * @param request This and all remaining parameters should be replaced by one
+  *                of the convenience macros in @ref opus_genericctls,
+  *                @ref opus_encoderctls, @ref opus_multistream_ctls, or
+  *                @ref opus_projection_ctls
+  * @see opus_genericctls
+  * @see opus_encoderctls
+  * @see opus_multistream_ctls
+  * @see opus_projection_ctls
+  */
+OPUS_EXPORT int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+
+
+/**@}*/
+
+/**\name Projection decoder functions */
+/**@{*/
+
+/** Gets the size of an <code>OpusProjectionDecoder</code> structure.
+  * @param channels <tt>int</tt>: The total number of output channels.
+  *                               This must be no more than 255.
+  * @param streams <tt>int</tt>: The total number of streams coded in the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
+  *                                      (2 channel) streams.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      coded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @returns The size in bytes on success, or a negative error code
+  *          (see @ref opus_errorcodes) on error.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_decoder_get_size(
+    int channels,
+    int streams,
+    int coupled_streams
+);
+
+
+/** Allocates and initializes a projection decoder state.
+  * Call opus_projection_decoder_destroy() to release
+  * this object when finished.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels to output.
+  *                               This must be at most 255.
+  *                               It may be different from the number of coded
+  *                               channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams coded in the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+  *                                      (2 channel) streams.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      coded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @param[in] demixing_matrix <tt>const unsigned char[demixing_matrix_size]</tt>: Demixing matrix
+  *                         that mapping from coded channels to output channels,
+  *                         as described in @ref opus_projection and
+  *                         @ref opus_projection_ctls.
+  * @param demixing_matrix_size <tt>opus_int32</tt>: The size in bytes of the
+  *                                                  demixing matrix, as
+  *                                                  described in @ref
+  *                                                  opus_projection_ctls.
+  * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
+  *                                   code (see @ref opus_errorcodes) on
+  *                                   failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionDecoder *opus_projection_decoder_create(
+    opus_int32 Fs,
+    int channels,
+    int streams,
+    int coupled_streams,
+    unsigned char *demixing_matrix,
+    opus_int32 demixing_matrix_size,
+    int *error
+) OPUS_ARG_NONNULL(5);
+
+
+/** Intialize a previously allocated projection decoder state object.
+  * The memory pointed to by \a st must be at least the size returned by
+  * opus_projection_decoder_get_size().
+  * This is intended for applications which use their own allocator instead of
+  * malloc.
+  * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
+  * @see opus_projection_decoder_create
+  * @see opus_projection_deocder_get_size
+  * @param st <tt>OpusProjectionDecoder*</tt>: Projection encoder state to initialize.
+  * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
+  *                                This must be one of 8000, 12000, 16000,
+  *                                24000, or 48000.
+  * @param channels <tt>int</tt>: Number of channels to output.
+  *                               This must be at most 255.
+  *                               It may be different from the number of coded
+  *                               channels (<code>streams +
+  *                               coupled_streams</code>).
+  * @param streams <tt>int</tt>: The total number of streams coded in the
+  *                              input.
+  *                              This must be no more than 255.
+  * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
+  *                                      (2 channel) streams.
+  *                                      This must be no larger than the total
+  *                                      number of streams.
+  *                                      Additionally, The total number of
+  *                                      coded channels (<code>streams +
+  *                                      coupled_streams</code>) must be no
+  *                                      more than 255.
+  * @param[in] demixing_matrix <tt>const unsigned char[demixing_matrix_size]</tt>: Demixing matrix
+  *                         that mapping from coded channels to output channels,
+  *                         as described in @ref opus_projection and
+  *                         @ref opus_projection_ctls.
+  * @param demixing_matrix_size <tt>opus_int32</tt>: The size in bytes of the
+  *                                                  demixing matrix, as
+  *                                                  described in @ref
+  *                                                  opus_projection_ctls.
+  * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
+  *          on failure.
+  */
+OPUS_EXPORT int opus_projection_decoder_init(
+    OpusProjectionDecoder *st,
+    opus_int32 Fs,
+    int channels,
+    int streams,
+    int coupled_streams,
+    unsigned char *demixing_matrix,
+    opus_int32 demixing_matrix_size
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
+
+
+/** Decode a projection Opus packet.
+  * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
+  * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+  *                                                Use a <code>NULL</code>
+  *                                                pointer to indicate packet
+  *                                                loss.
+  * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+  * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+  *                                       samples.
+  *                                       This must contain room for
+  *                                       <code>frame_size*channels</code>
+  *                                       samples.
+  * @param frame_size <tt>int</tt>: The number of samples per channel of
+  *                                 available space in \a pcm.
+  *                                 If this is less than the maximum packet duration
+  *                                 (120 ms; 5760 for 48kHz), this function will not be capable
+  *                                 of decoding some packets. In the case of PLC (data==NULL)
+  *                                 or FEC (decode_fec=1), then frame_size needs to be exactly
+  *                                 the duration of audio that is missing, otherwise the
+  *                                 decoder will not be in the optimal state to decode the
+  *                                 next incoming packet. For the PLC and FEC cases, frame_size
+  *                                 <b>must</b> be a multiple of 2.5 ms.
+  * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+  *                                 forward error correction data be decoded.
+  *                                 If no such data is available, the frame is
+  *                                 decoded as if it were lost.
+  * @returns Number of samples decoded on success or a negative error code
+  *          (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode(
+    OpusProjectionDecoder *st,
+    const unsigned char *data,
+    opus_int32 len,
+    opus_int16 *pcm,
+    int frame_size,
+    int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+
+/** Decode a projection Opus packet with floating point output.
+  * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
+  * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+  *                                                Use a <code>NULL</code>
+  *                                                pointer to indicate packet
+  *                                                loss.
+  * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+  * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
+  *                                       samples.
+  *                                       This must contain room for
+  *                                       <code>frame_size*channels</code>
+  *                                       samples.
+  * @param frame_size <tt>int</tt>: The number of samples per channel of
+  *                                 available space in \a pcm.
+  *                                 If this is less than the maximum packet duration
+  *                                 (120 ms; 5760 for 48kHz), this function will not be capable
+  *                                 of decoding some packets. In the case of PLC (data==NULL)
+  *                                 or FEC (decode_fec=1), then frame_size needs to be exactly
+  *                                 the duration of audio that is missing, otherwise the
+  *                                 decoder will not be in the optimal state to decode the
+  *                                 next incoming packet. For the PLC and FEC cases, frame_size
+  *                                 <b>must</b> be a multiple of 2.5 ms.
+  * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+  *                                 forward error correction data be decoded.
+  *                                 If no such data is available, the frame is
+  *                                 decoded as if it were lost.
+  * @returns Number of samples decoded on success or a negative error code
+  *          (see @ref opus_errorcodes) on failure.
+  */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode_float(
+    OpusProjectionDecoder *st,
+    const unsigned char *data,
+    opus_int32 len,
+    float *pcm,
+    int frame_size,
+    int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+
+/** Perform a CTL function on a projection Opus decoder.
+  *
+  * Generally the request and subsequent arguments are generated by a
+  * convenience macro.
+  * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
+  * @param request This and all remaining parameters should be replaced by one
+  *                of the convenience macros in @ref opus_genericctls,
+  *                @ref opus_decoderctls, @ref opus_multistream_ctls, or
+  *                @ref opus_projection_ctls.
+  * @see opus_genericctls
+  * @see opus_decoderctls
+  * @see opus_multistream_ctls
+  * @see opus_projection_ctls
+  */
+OPUS_EXPORT int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
+
+
+/** Frees an <code>OpusProjectionDecoder</code> allocated by
+  * opus_projection_decoder_create().
+  * @param st <tt>OpusProjectionDecoder</tt>: Projection decoder state to be freed.
+  */
+OPUS_EXPORT void opus_projection_decoder_destroy(OpusProjectionDecoder *st);
+
+
+/**@}*/
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPUS_PROJECTION_H */
diff --git a/include/opus_types.h b/include/opus_types.h
index 7180826..7cf6755 100644
--- a/include/opus_types.h
+++ b/include/opus_types.h
@@ -33,14 +33,29 @@
 #ifndef OPUS_TYPES_H
 #define OPUS_TYPES_H
 
+#define opus_int         int                     /* used for counters etc; at least 16 bits */
+#define opus_int64       long long
+#define opus_int8        signed char
+
+#define opus_uint        unsigned int            /* used for counters etc; at least 16 bits */
+#define opus_uint64      unsigned long long
+#define opus_uint8       unsigned char
+
 /* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.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>
-
+#  undef opus_int64
+#  undef opus_int8
+#  undef opus_uint64
+#  undef opus_uint8
+   typedef int8_t opus_int8;
+   typedef uint8_t opus_uint8;
    typedef int16_t opus_int16;
    typedef uint16_t opus_uint16;
    typedef int32_t opus_int32;
    typedef uint32_t opus_uint32;
+   typedef int64_t opus_int64;
+   typedef uint64_t opus_uint64;
 #elif defined(_WIN32)
 
 #  if defined(__CYGWIN__)
@@ -148,12 +163,4 @@
 
 #endif
 
-#define opus_int         int                     /* used for counters etc; at least 16 bits */
-#define opus_int64       long long
-#define opus_int8        signed char
-
-#define opus_uint        unsigned int            /* used for counters etc; at least 16 bits */
-#define opus_uint64      unsigned long long
-#define opus_uint8       unsigned char
-
 #endif  /* OPUS_TYPES_H */
diff --git a/m4/ax_add_fortify_source.m4 b/m4/ax_add_fortify_source.m4
new file mode 100644
index 0000000..1c89e41
--- /dev/null
+++ b/m4/ax_add_fortify_source.m4
@@ -0,0 +1,53 @@
+# ===========================================================================
+#   Modified from https://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_ADD_FORTIFY_SOURCE
+#
+# DESCRIPTION
+#
+#   Check whether -D_FORTIFY_SOURCE=2 can be added to CFLAGS without macro
+#   redefinition warnings. Some distributions (such as Gentoo Linux) enable
+#   _FORTIFY_SOURCE globally in their compilers, leading to unnecessary
+#   warnings in the form of
+#
+#     <command-line>:0:0: error: "_FORTIFY_SOURCE" redefined [-Werror]
+#     <built-in>: note: this is the location of the previous definition
+#
+#   which is a problem if -Werror is enabled. This macro checks whether
+#   _FORTIFY_SOURCE is already defined, and if not, adds -D_FORTIFY_SOURCE=2
+#   to CFLAGS.
+#
+# LICENSE
+#
+#   Copyright (c) 2017 David Seifert <soap@gentoo.org>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_ADD_FORTIFY_SOURCE],[
+    AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CFLAGS])
+    AC_LINK_IFELSE([
+        AC_LANG_SOURCE(
+            [[
+                int main() {
+                #ifndef _FORTIFY_SOURCE
+                    return 0;
+                #else
+                    this_is_an_error;
+                #endif
+                }
+            ]]
+        )], [
+            AC_MSG_RESULT([yes])
+            CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2"
+        ], [
+            AC_MSG_RESULT([no])
+    ])
+])
diff --git a/opus-uninstalled.pc.in b/opus-uninstalled.pc.in
index 3f2d674..19f5c93 100644
--- a/opus-uninstalled.pc.in
+++ b/opus-uninstalled.pc.in
@@ -8,5 +8,5 @@
 Version: @VERSION@
 Requires:
 Conflicts:
-Libs: ${libdir}/libopus.a @LIBM@
+Libs: ${libdir}/libopus.la @LIBM@
 Cflags: -I${pcfiledir}/@top_srcdir@/include
diff --git a/opus_headers.mk b/opus_headers.mk
index 43a978c..27596f2 100644
--- a/opus_headers.mk
+++ b/opus_headers.mk
@@ -1,7 +1,9 @@
 OPUS_HEAD = \
 include/opus.h \
 include/opus_multistream.h \
+include/opus_projection.h \
 src/opus_private.h \
 src/analysis.h \
+src/mapping_matrix.h \
 src/mlp.h \
 src/tansig_table.h
diff --git a/opus_sources.mk b/opus_sources.mk
index e4eeb91..b0763f9 100644
--- a/opus_sources.mk
+++ b/opus_sources.mk
@@ -4,7 +4,10 @@
 src/opus_multistream.c \
 src/opus_multistream_encoder.c \
 src/opus_multistream_decoder.c \
-src/repacketizer.c
+src/repacketizer.c \
+src/opus_projection_encoder.c \
+src/opus_projection_decoder.c \
+src/mapping_matrix.c
 
 OPUS_SOURCES_FLOAT = \
 src/analysis.c \
diff --git a/releases.sha2 b/releases.sha2
index 19ce21f..76170ac 100644
--- a/releases.sha2
+++ b/releases.sha2
@@ -35,6 +35,9 @@
 291e979a8a2fb679ed35a5dff5d761a9d9a5e22586fd07934ed94461e2636c7a  opus-1.2-beta.tar.gz
 85343fdaed96529d94c1e1f3a210fa51240d04ca62fa01e97ef02f88020c2ce9  opus-1.2-rc1.tar.gz
 77db45a87b51578fbc49555ef1b10926179861d854eb2613207dc79d9ec0a9a9  opus-1.2.tar.gz
+cfafd339ccd9c5ef8d6ab15d7e1a412c054bf4cb4ecbbbcc78c12ef2def70732  opus-1.2.1.tar.gz
+7f56e058c9549d03ae35511ad9e16ef6d1eb257836830d54abff0f495f17e187  opus-1.3-beta.tar.gz
+96fa28598e8ccd558b297277ad59a045c551ba0e06d65a9675938e084f837669  opus-1.3-rc.tar.gz
 94ac78ca4f74c4e43bc9fe4ec1ad0aa36f38ab90f45b0727c40dd1e96096e767  opus_testvectors-draft11.tar.gz
 94ac78ca4f74c4e43bc9fe4ec1ad0aa36f38ab90f45b0727c40dd1e96096e767  opus_testvectors.tar.gz
 5d2b99757bcb628bab2611f3ed27af6f35276ce3abc96c0ed4399d6c6463dda5  opus-tools-0.1.2.tar.gz
diff --git a/scripts/dump_rnn.py b/scripts/dump_rnn.py
new file mode 100755
index 0000000..dd66403
--- /dev/null
+++ b/scripts/dump_rnn.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+from keras.models import Sequential
+from keras.layers import Dense
+from keras.layers import LSTM
+from keras.layers import GRU
+from keras.models import load_model
+from keras import backend as K
+
+import numpy as np
+
+def printVector(f, vector, name):
+    v = np.reshape(vector, (-1));
+    #print('static const float ', name, '[', len(v), '] = \n', file=f)
+    f.write('static const opus_int16 {}[{}] = {{\n   '.format(name, len(v)))
+    for i in range(0, len(v)):
+        f.write('{}'.format(int(round(8192*v[i]))))
+        if (i!=len(v)-1):
+            f.write(',')
+        else:
+            break;
+        if (i%8==7):
+            f.write("\n   ")
+        else:
+            f.write(" ")
+    #print(v, file=f)
+    f.write('\n};\n\n')
+    return;
+
+def binary_crossentrop2(y_true, y_pred):
+        return K.mean(2*K.abs(y_true-0.5) * K.binary_crossentropy(y_pred, y_true), axis=-1)
+
+
+model = load_model("weights.hdf5", custom_objects={'binary_crossentrop2': binary_crossentrop2})
+
+weights = model.get_weights()
+
+f = open('rnn_weights.c', 'w')
+
+f.write('/*This file is automatically generated from a Keras model*/\n\n')
+f.write('#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n#include "mlp.h"\n\n')
+
+printVector(f, weights[0], 'layer0_weights')
+printVector(f, weights[1], 'layer0_bias')
+printVector(f, weights[2], 'layer1_weights')
+printVector(f, weights[3], 'layer1_recur_weights')
+printVector(f, weights[4], 'layer1_bias')
+printVector(f, weights[5], 'layer2_weights')
+printVector(f, weights[6], 'layer2_bias')
+
+f.write('const DenseLayer layer0 = {\n   layer0_bias,\n   layer0_weights,\n   25, 16, 0\n};\n\n')
+f.write('const GRULayer layer1 = {\n   layer1_bias,\n   layer1_weights,\n   layer1_recur_weights,\n   16, 12\n};\n\n')
+f.write('const DenseLayer layer2 = {\n   layer2_bias,\n   layer2_weights,\n   12, 2, 1\n};\n\n')
+
+f.close()
diff --git a/scripts/rnn_train.py b/scripts/rnn_train.py
new file mode 100755
index 0000000..ffdaa1e
--- /dev/null
+++ b/scripts/rnn_train.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+from keras.models import Sequential
+from keras.models import Model
+from keras.layers import Input
+from keras.layers import Dense
+from keras.layers import LSTM
+from keras.layers import GRU
+from keras.layers import SimpleRNN
+from keras.layers import Dropout
+from keras import losses
+import h5py
+
+from keras import backend as K
+import numpy as np
+
+def binary_crossentrop2(y_true, y_pred):
+    return K.mean(2*K.abs(y_true-0.5) * K.binary_crossentropy(y_pred, y_true), axis=-1)
+
+print('Build model...')
+#model = Sequential()
+#model.add(Dense(16, activation='tanh', input_shape=(None, 25)))
+#model.add(GRU(12, dropout=0.0, recurrent_dropout=0.0, activation='tanh', recurrent_activation='sigmoid', return_sequences=True))
+#model.add(Dense(2, activation='sigmoid'))
+
+main_input = Input(shape=(None, 25), name='main_input')
+x = Dense(16, activation='tanh')(main_input)
+x = GRU(12, dropout=0.1, recurrent_dropout=0.1, activation='tanh', recurrent_activation='sigmoid', return_sequences=True)(x)
+x = Dense(2, activation='sigmoid')(x)
+model = Model(inputs=main_input, outputs=x)
+
+batch_size = 64
+
+print('Loading data...')
+with h5py.File('features.h5', 'r') as hf:
+    all_data = hf['features'][:]
+print('done.')
+
+window_size = 1500
+
+nb_sequences = len(all_data)/window_size
+print(nb_sequences, ' sequences')
+x_train = all_data[:nb_sequences*window_size, :-2]
+x_train = np.reshape(x_train, (nb_sequences, window_size, 25))
+
+y_train = np.copy(all_data[:nb_sequences*window_size, -2:])
+y_train = np.reshape(y_train, (nb_sequences, window_size, 2))
+
+all_data = 0;
+x_train = x_train.astype('float32')
+y_train = y_train.astype('float32')
+
+print(len(x_train), 'train sequences. x shape =', x_train.shape, 'y shape = ', y_train.shape)
+
+# try using different optimizers and different optimizer configs
+model.compile(loss=binary_crossentrop2,
+              optimizer='adam',
+              metrics=['binary_accuracy'])
+
+print('Train...')
+model.fit(x_train, y_train,
+          batch_size=batch_size,
+          epochs=200,
+          validation_data=(x_train, y_train))
+model.save("newweights.hdf5")
diff --git a/silk/API.h b/silk/API.h
index 0131acb..4d90ff9 100644
--- a/silk/API.h
+++ b/silk/API.h
@@ -80,7 +80,8 @@
     opus_int                        nSamplesIn,         /* I    Number of samples in input vector               */
     ec_enc                          *psRangeEnc,        /* I/O  Compressor data structure                       */
     opus_int32                      *nBytesOut,         /* I/O  Number of bytes in payload (input: Max bytes)   */
-    const opus_int                  prefillFlag         /* I    Flag to indicate prefilling buffers no coding   */
+    const opus_int                  prefillFlag,        /* I    Flag to indicate prefilling buffers no coding   */
+    int                             activity            /* I    Decision of Opus voice activity detector        */
 );
 
 /****************************************/
diff --git a/silk/CNG.c b/silk/CNG.c
index e6d9b86..ef8e38d 100644
--- a/silk/CNG.c
+++ b/silk/CNG.c
@@ -146,8 +146,8 @@
 
         /* Generate CNG signal, by synthesis filtering */
         silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
+        celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
         for( i = 0; i < length; i++ ) {
-            silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
             /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
             LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
             LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i -  1 ], A_Q12[ 0 ] );
diff --git a/silk/LPC_analysis_filter.c b/silk/LPC_analysis_filter.c
index 7715f70..d34b5eb 100644
--- a/silk/LPC_analysis_filter.c
+++ b/silk/LPC_analysis_filter.c
@@ -64,12 +64,12 @@
     const opus_int16 *in_ptr;
 #endif
 
-    silk_assert( d >= 6 );
-    silk_assert( (d & 1) == 0 );
-    silk_assert( d <= len );
+    celt_assert( d >= 6 );
+    celt_assert( (d & 1) == 0 );
+    celt_assert( d <= len );
 
 #if defined(FIXED_POINT) && USE_CELT_FIR
-    silk_assert( d <= SILK_MAX_ORDER_LPC );
+    celt_assert( d <= SILK_MAX_ORDER_LPC );
     for ( j = 0; j < d; j++ ) {
         num[ j ] = -B[ j ];
     }
diff --git a/silk/NLSF2A.c b/silk/NLSF2A.c
index 116b465..d5b7730 100644
--- a/silk/NLSF2A.c
+++ b/silk/NLSF2A.c
@@ -86,7 +86,7 @@
     opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
 
     silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
-    silk_assert( d==10 || d==16 );
+    celt_assert( d==10 || d==16 );
 
     /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
     ordering = d == 16 ? ordering16 : ordering10;
diff --git a/silk/NLSF_VQ.c b/silk/NLSF_VQ.c
index 452f3dc..b83182a 100644
--- a/silk/NLSF_VQ.c
+++ b/silk/NLSF_VQ.c
@@ -46,7 +46,7 @@
     const opus_int16 *w_Q9_ptr;
     const opus_uint8 *cb_Q8_ptr;
 
-    silk_assert( ( LPC_order & 1 ) == 0 );
+    celt_assert( ( LPC_order & 1 ) == 0 );
 
     /* Loop over codebook */
     cb_Q8_ptr = pCB_Q8;
diff --git a/silk/NLSF_VQ_weights_laroia.c b/silk/NLSF_VQ_weights_laroia.c
index 04894c5..9873bcd 100644
--- a/silk/NLSF_VQ_weights_laroia.c
+++ b/silk/NLSF_VQ_weights_laroia.c
@@ -48,8 +48,8 @@
     opus_int   k;
     opus_int32 tmp1_int, tmp2_int;
 
-    silk_assert( D > 0 );
-    silk_assert( ( D & 1 ) == 0 );
+    celt_assert( D > 0 );
+    celt_assert( ( D & 1 ) == 0 );
 
     /* First value */
     tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 );
diff --git a/silk/NLSF_encode.c b/silk/NLSF_encode.c
index 268b9a1..01ac7db 100644
--- a/silk/NLSF_encode.c
+++ b/silk/NLSF_encode.c
@@ -60,7 +60,7 @@
     const opus_int16 *pCB_Wght_Q9;
     SAVE_STACK;
 
-    silk_assert( signalType >= 0 && signalType <= 2 );
+    celt_assert( signalType >= 0 && signalType <= 2 );
     silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
 
     /* NLSF stabilization */
diff --git a/silk/NSQ.c b/silk/NSQ.c
index 617a19f..1d64d8e 100644
--- a/silk/NSQ.c
+++ b/silk/NSQ.c
@@ -143,7 +143,7 @@
             if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
                 /* Rewhiten with new A coefs */
                 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
-                silk_assert( start_idx > 0 );
+                celt_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 );
@@ -247,7 +247,7 @@
         }
 
         /* Noise shape feedback */
-        silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
+        celt_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
         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 );
@@ -255,7 +255,7 @@
         n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
         n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
 
-        silk_assert( lag > 0 || signalType != TYPE_VOICED );
+        celt_assert( lag > 0 || signalType != TYPE_VOICED );
 
         /* Combine prediction and noise shaping signals */
         tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 );        /* Q12 */
diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c
index 1cd29d9..3fd9fa0 100644
--- a/silk/NSQ_del_dec.c
+++ b/silk/NSQ_del_dec.c
@@ -250,7 +250,7 @@
 
                 /* Rewhiten with new A coefs */
                 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
-                silk_assert( start_idx > 0 );
+                celt_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 );
@@ -361,7 +361,7 @@
     NSQ_sample_struct  *psSS;
     SAVE_STACK;
 
-    silk_assert( nStatesDelayedDecision > 0 );
+    celt_assert( nStatesDelayedDecision > 0 );
     ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
 
     shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
@@ -419,7 +419,7 @@
             LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 );                              /* Q10 -> Q14 */
 
             /* Noise shape feedback */
-            silk_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
+            celt_assert( ( shapingLPCOrder & 1 ) == 0 );   /* check that order is even */
             /* Output of lowpass section */
             tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 );
             /* Output of allpass section */
diff --git a/silk/PLC.c b/silk/PLC.c
index a3e55ea..f893916 100644
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -291,7 +291,7 @@
 
     /* Rewhiten LTP state */
     idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
-    silk_assert( idx > 0 );
+    celt_assert( idx > 0 );
     silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch );
     /* Scale LTP state */
     inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 );
@@ -347,7 +347,7 @@
     /* Copy LPC state */
     silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
 
-    silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
+    celt_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
     for( i = 0; i < psDec->frame_length; i++ ) {
         /* partly unrolled */
         /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
diff --git a/silk/VAD.c b/silk/VAD.c
index 0a782af..d0cda52 100644
--- a/silk/VAD.c
+++ b/silk/VAD.c
@@ -101,9 +101,9 @@
 
     /* Safety checks */
     silk_assert( VAD_N_BANDS == 4 );
-    silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
-    silk_assert( psEncC->frame_length <= 512 );
-    silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
+    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
+    celt_assert( psEncC->frame_length <= 512 );
+    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
 
     /***********************/
     /* Filter and Decimate */
@@ -252,15 +252,14 @@
         speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
     }
 
+    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
+        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
+    }
     /* Power scaling */
     if( speech_nrg <= 0 ) {
         SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
-    } else if( speech_nrg < 32768 ) {
-        if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
-            speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );
-        } else {
-            speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );
-        }
+    } else if( speech_nrg < 16384 ) {
+        speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
 
         /* square-root */
         speech_nrg = silk_SQRT_APPROX( speech_nrg );
@@ -313,6 +312,8 @@
     /* Initially faster smoothing */
     if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
         min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
+        /* Increment frame counter */
+        psSilk_VAD->counter++;
     } else {
         min_coef = 0;
     }
@@ -356,7 +357,4 @@
         /* Store as part of state */
         psSilk_VAD->NL[ k ] = nl;
     }
-
-    /* Increment frame counter */
-    psSilk_VAD->counter++;
 }
diff --git a/silk/arm/LPC_inv_pred_gain_neon_intr.c b/silk/arm/LPC_inv_pred_gain_neon_intr.c
index 27142f3..ab426bc 100644
--- a/silk/arm/LPC_inv_pred_gain_neon_intr.c
+++ b/silk/arm/LPC_inv_pred_gain_neon_intr.c
@@ -217,13 +217,13 @@
         {
         case 24:
             t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 );
-            /* Intend to fall through */
+            /* FALLTHROUGH */
 
         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 */
+            /* FALLTHROUGH */
 
         case 8:
         {
@@ -246,17 +246,17 @@
         case 6:
             DC_resp += (opus_int32)A_Q12[ 5 ];
             DC_resp += (opus_int32)A_Q12[ 4 ];
-            /* Intend to fall through */
+            /* FALLTHROUGH */
 
         case 4:
             DC_resp += (opus_int32)A_Q12[ 3 ];
             DC_resp += (opus_int32)A_Q12[ 2 ];
-            /* Intend to fall through */
+            /* FALLTHROUGH */
 
         case 2:
             DC_resp += (opus_int32)A_Q12[ 1 ];
             DC_resp += (opus_int32)A_Q12[ 0 ];
-            /* Intend to fall through */
+            /* FALLTHROUGH */
 
         default:
             break;
diff --git a/silk/check_control_input.c b/silk/check_control_input.c
index b5de9ce..739fb01 100644
--- a/silk/check_control_input.c
+++ b/silk/check_control_input.c
@@ -38,7 +38,7 @@
     silk_EncControlStruct        *encControl                    /* I    Control structure                           */
 )
 {
-    silk_assert( encControl != NULL );
+    celt_assert( encControl != NULL );
 
     if( ( ( encControl->API_sampleRate            !=  8000 ) &&
           ( encControl->API_sampleRate            != 12000 ) &&
@@ -59,46 +59,46 @@
           ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) ||
           ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) ||
           ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_FS_NOT_SUPPORTED;
     }
     if( encControl->payloadSize_ms != 10 &&
         encControl->payloadSize_ms != 20 &&
         encControl->payloadSize_ms != 40 &&
         encControl->payloadSize_ms != 60 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
     }
     if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_LOSS_RATE;
     }
     if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_DTX_SETTING;
     }
     if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_CBR_SETTING;
     }
     if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_INBAND_FEC_SETTING;
     }
     if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
     }
     if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
     }
     if( encControl->nChannelsInternal > encControl->nChannelsAPI ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
     }
     if( encControl->complexity < 0 || encControl->complexity > 10 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         return SILK_ENC_INVALID_COMPLEXITY_SETTING;
     }
 
diff --git a/silk/control_SNR.c b/silk/control_SNR.c
index 464c1ac..9a6db27 100644
--- a/silk/control_SNR.c
+++ b/silk/control_SNR.c
@@ -32,44 +32,82 @@
 #include "main.h"
 #include "tuning_parameters.h"
 
+/* These tables hold SNR values divided by 21 (so they fit in 8 bits)
+   for different target bitrates spaced at 400 bps interval. The first
+   10 values are omitted (0-4 kb/s) because they're all zeros.
+   These tables were obtained by running different SNRs through the
+   encoder and measuring the active bitrate. */
+static const unsigned char silk_TargetRate_NB_21[117 - 10] = {
+                                              0, 15, 39, 52, 61, 68,
+     74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124,
+    126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157,
+    158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182,
+    183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204,
+    205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225,
+    227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248,
+    249,250,252,253,255
+};
+
+static const unsigned char silk_TargetRate_MB_21[165 - 10] = {
+                                              0,  0, 28, 43, 52, 59,
+     65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109,
+    111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136,
+    137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157,
+    158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175,
+    176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190,
+    191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205,
+    206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,
+    221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235,
+    236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,
+    251,252,253,254,255
+};
+
+static const unsigned char silk_TargetRate_WB_21[201 - 10] = {
+                                              0,  0,  0,  8, 29, 41,
+     49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99,
+    101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125,
+    126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144,
+    145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160,
+    161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175,
+    176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188,
+    189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200,
+    200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211,
+    212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,
+    224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234,
+    235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246,
+    247,248,249,249,250,251,252,253,255
+};
+
 /* Control SNR of redidual quantizer */
 opus_int silk_control_SNR(
     silk_encoder_state          *psEncC,                        /* I/O  Pointer to Silk encoder state               */
     opus_int32                  TargetRate_bps                  /* I    Target max bitrate (bps)                    */
 )
 {
-    opus_int k, ret = SILK_NO_ERROR;
-    opus_int32 frac_Q6;
-    const opus_int32 *rateTable;
+    int id;
+    int bound;
+    const unsigned char *snr_table;
 
-    /* Set bitrate/coding quality */
-    TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
-    if( TargetRate_bps != psEncC->TargetRate_bps ) {
-        psEncC->TargetRate_bps = TargetRate_bps;
-
-        /* If new TargetRate_bps, translate to SNR_dB value */
-        if( psEncC->fs_kHz == 8 ) {
-            rateTable = silk_TargetRate_table_NB;
-        } else if( psEncC->fs_kHz == 12 ) {
-            rateTable = silk_TargetRate_table_MB;
-        } else {
-            rateTable = silk_TargetRate_table_WB;
-        }
-
-        /* Reduce bitrate for 10 ms modes in these calculations */
-        if( psEncC->nb_subfr == 2 ) {
-            TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;
-        }
-
-        /* 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 ] );
-                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;
-            }
-        }
+    psEncC->TargetRate_bps = TargetRate_bps;
+    if( psEncC->nb_subfr == 2 ) {
+        TargetRate_bps -= 2000 + psEncC->fs_kHz/16;
     }
-
-    return ret;
+    if( psEncC->fs_kHz == 8 ) {
+        bound = sizeof(silk_TargetRate_NB_21);
+        snr_table = silk_TargetRate_NB_21;
+    } else if( psEncC->fs_kHz == 12 ) {
+        bound = sizeof(silk_TargetRate_MB_21);
+        snr_table = silk_TargetRate_MB_21;
+    } else {
+        bound = sizeof(silk_TargetRate_WB_21);
+        snr_table = silk_TargetRate_WB_21;
+    }
+    id = (TargetRate_bps+200)/400;
+    id = silk_min(id - 10, bound-1);
+    if( id <= 0 ) {
+        psEncC->SNR_dB_Q7 = 0;
+    } else {
+        psEncC->SNR_dB_Q7 = snr_table[id]*21;
+    }
+    return SILK_NO_ERROR;
 }
diff --git a/silk/control_audio_bandwidth.c b/silk/control_audio_bandwidth.c
index 4f9bc5c..f6d22d8 100644
--- a/silk/control_audio_bandwidth.c
+++ b/silk/control_audio_bandwidth.c
@@ -39,9 +39,15 @@
 )
 {
     opus_int   fs_kHz;
+    opus_int   orig_kHz;
     opus_int32 fs_Hz;
 
-    fs_kHz = psEncC->fs_kHz;
+    orig_kHz = psEncC->fs_kHz;
+    /* Handle a bandwidth-switching reset where we need to be aware what the last sampling rate was. */
+    if( orig_kHz == 0 ) {
+        orig_kHz = psEncC->sLP.saved_fs_kHz;
+    }
+    fs_kHz = orig_kHz;
     fs_Hz = silk_SMULBB( fs_kHz, 1000 );
     if( fs_Hz == 0 ) {
         /* Encoder has just been initialized */
@@ -61,7 +67,7 @@
         }
         if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {
             /* Check if we should switch down */
-            if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
+            if( silk_SMULBB( orig_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
             {
                 /* Switch down */
                 if( psEncC->sLP.mode == 0 ) {
@@ -76,7 +82,7 @@
                     psEncC->sLP.mode = 0;
 
                     /* Switch to a lower sample frequency */
-                    fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8;
+                    fs_kHz = orig_kHz == 16 ? 12 : 8;
                 } else {
                    if( psEncC->sLP.transition_frame_no <= 0 ) {
                        encControl->switchReady = 1;
@@ -90,12 +96,12 @@
             }
             else
             /* Check if we should switch up */
-            if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
+            if( silk_SMULBB( orig_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
             {
                 /* Switch up */
                 if( encControl->opusCanSwitch ) {
                     /* Switch to a higher sample frequency */
-                    fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16;
+                    fs_kHz = orig_kHz == 8 ? 12 : 16;
 
                     /* New transition */
                     psEncC->sLP.transition_frame_no = 0;
diff --git a/silk/control_codec.c b/silk/control_codec.c
index 9350fd4..52aa8fd 100644
--- a/silk/control_codec.c
+++ b/silk/control_codec.c
@@ -238,8 +238,8 @@
     }
 
     /* Set internal sampling frequency */
-    silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
-    silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
+    celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
+    celt_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
     if( psEnc->sCmn.fs_kHz != fs_kHz ) {
         /* reset part of the state */
         silk_memset( &psEnc->sShape,               0, sizeof( psEnc->sShape ) );
@@ -299,7 +299,7 @@
     }
 
     /* Check that settings are valid */
-    silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
+    celt_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
 
     return ret;
 }
@@ -312,7 +312,7 @@
     opus_int ret = 0;
 
     /* Set encoding complexity */
-    silk_assert( Complexity >= 0 && Complexity <= 10 );
+    celt_assert( Complexity >= 0 && Complexity <= 10 );
     if( Complexity < 1 ) {
         psEncC->pitchEstimationComplexity       = SILK_PE_MIN_COMPLEX;
         psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.8, 16 );
@@ -390,12 +390,12 @@
     psEncC->shapeWinLength          = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
     psEncC->Complexity              = Complexity;
 
-    silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
-    silk_assert( psEncC->shapingLPCOrder         <= MAX_SHAPE_LPC_ORDER      );
-    silk_assert( psEncC->nStatesDelayedDecision  <= MAX_DEL_DEC_STATES       );
-    silk_assert( psEncC->warping_Q16             <= 32767                    );
-    silk_assert( psEncC->la_shape                <= LA_SHAPE_MAX             );
-    silk_assert( psEncC->shapeWinLength          <= SHAPE_LPC_WIN_MAX        );
+    celt_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
+    celt_assert( psEncC->shapingLPCOrder         <= MAX_SHAPE_LPC_ORDER      );
+    celt_assert( psEncC->nStatesDelayedDecision  <= MAX_DEL_DEC_STATES       );
+    celt_assert( psEncC->warping_Q16             <= 32767                    );
+    celt_assert( psEncC->la_shape                <= LA_SHAPE_MAX             );
+    celt_assert( psEncC->shapeWinLength          <= SHAPE_LPC_WIN_MAX        );
 
     return ret;
 }
diff --git a/silk/dec_API.c b/silk/dec_API.c
index b7d8ed4..7d5ca7f 100644
--- a/silk/dec_API.c
+++ b/silk/dec_API.c
@@ -104,7 +104,7 @@
     int delay_stack_alloc;
     SAVE_STACK;
 
-    silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
+    celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
 
     /**********************************/
     /* Test if first frame in payload */
@@ -143,13 +143,13 @@
                 channel_state[ n ].nFramesPerPacket = 3;
                 channel_state[ n ].nb_subfr = 4;
             } else {
-                silk_assert( 0 );
+                celt_assert( 0 );
                 RESTORE_STACK;
                 return SILK_DEC_INVALID_FRAME_SIZE;
             }
             fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
             if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
-                silk_assert( 0 );
+                celt_assert( 0 );
                 RESTORE_STACK;
                 return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
             }
diff --git a/silk/decode_core.c b/silk/decode_core.c
index fd4e857..1c352a6 100644
--- a/silk/decode_core.c
+++ b/silk/decode_core.c
@@ -141,7 +141,7 @@
             if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {
                 /* Rewhiten with new A coefs */
                 start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
-                silk_assert( start_idx > 0 );
+                celt_assert( start_idx > 0 );
 
                 if( k == 2 ) {
                     silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );
@@ -196,7 +196,7 @@
 
         for( i = 0; i < psDec->subfr_length; i++ ) {
             /* Short-term prediction */
-            silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
+            celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
             /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
             LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
             LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], A_Q12_tmp[ 0 ] );
diff --git a/silk/decode_frame.c b/silk/decode_frame.c
index dfa73c4..e73825b 100644
--- a/silk/decode_frame.c
+++ b/silk/decode_frame.c
@@ -55,7 +55,7 @@
     psDecCtrl->LTP_scale_Q14 = 0;
 
     /* Safety checks */
-    silk_assert( L > 0 && L <= MAX_FRAME_LENGTH );
+    celt_assert( L > 0 && L <= MAX_FRAME_LENGTH );
 
     if(   lostFlag == FLAG_DECODE_NORMAL ||
         ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) )
@@ -91,7 +91,7 @@
 
         psDec->lossCnt = 0;
         psDec->prevSignalType = psDec->indices.signalType;
-        silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
+        celt_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
 
         /* A frame has been decoded without errors */
         psDec->first_frame_after_reset = 0;
@@ -104,7 +104,7 @@
     /*************************/
     /* Update output buffer. */
     /*************************/
-    silk_assert( psDec->ltp_mem_length >= psDec->frame_length );
+    celt_assert( psDec->ltp_mem_length >= psDec->frame_length );
     mv_len = psDec->ltp_mem_length - psDec->frame_length;
     silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) );
     silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) );
diff --git a/silk/decode_indices.c b/silk/decode_indices.c
index 7afe5c2..0bb4a99 100644
--- a/silk/decode_indices.c
+++ b/silk/decode_indices.c
@@ -79,7 +79,7 @@
     /**********************/
     psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 );
     silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] );
-    silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
+    celt_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
     for( i = 0; i < psDec->psNLSF_CB->order; i++ ) {
         Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
         if( Ix == 0 ) {
diff --git a/silk/decode_pitch.c b/silk/decode_pitch.c
index fedbc6a..fd1b6bf 100644
--- a/silk/decode_pitch.c
+++ b/silk/decode_pitch.c
@@ -51,7 +51,7 @@
             Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
             cbk_size   = PE_NB_CBKS_STAGE2_EXT;
         } else {
-            silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
+            celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
             Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
             cbk_size   = PE_NB_CBKS_STAGE2_10MS;
         }
@@ -60,7 +60,7 @@
             Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
             cbk_size   = PE_NB_CBKS_STAGE3_MAX;
         } else {
-            silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
+            celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
             Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
             cbk_size   = PE_NB_CBKS_STAGE3_10MS;
         }
diff --git a/silk/decode_pulses.c b/silk/decode_pulses.c
index d6bbec9..a56d2d3 100644
--- a/silk/decode_pulses.c
+++ b/silk/decode_pulses.c
@@ -56,7 +56,7 @@
     silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
     iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
     if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
-        silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
+        celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
         iter++;
     }
 
diff --git a/silk/decoder_set_fs.c b/silk/decoder_set_fs.c
index eef0fd2..d9a13d0 100644
--- a/silk/decoder_set_fs.c
+++ b/silk/decoder_set_fs.c
@@ -40,8 +40,8 @@
 {
     opus_int frame_length, ret = 0;
 
-    silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
-    silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
+    celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
+    celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
 
     /* New (sub)frame length */
     psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz );
@@ -86,7 +86,7 @@
                 psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
             } else {
                 /* unsupported sampling rate */
-                silk_assert( 0 );
+                celt_assert( 0 );
             }
             psDec->first_frame_after_reset = 1;
             psDec->lagPrev                 = 100;
@@ -101,7 +101,7 @@
     }
 
     /* Check that settings are valid */
-    silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
+    celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
 
     return ret;
 }
diff --git a/silk/define.h b/silk/define.h
index 1286048..247cb0b 100644
--- a/silk/define.h
+++ b/silk/define.h
@@ -46,7 +46,6 @@
 /* Limits on bitrate */
 #define MIN_TARGET_RATE_BPS                     5000
 #define MAX_TARGET_RATE_BPS                     80000
-#define TARGET_RATE_TAB_SZ                      8
 
 /* LBRR thresholds */
 #define LBRR_NB_MIN_RATE_BPS                    12000
@@ -58,6 +57,11 @@
 #define MAX_CONSECUTIVE_DTX                     20      /* eq 400 ms */
 #define DTX_ACTIVITY_THRESHOLD                  0.1f
 
+/* VAD decision */
+#define VAD_NO_DECISION                         -1
+#define VAD_NO_ACTIVITY                         0
+#define VAD_ACTIVITY                            1
+
 /* Maximum sampling frequency */
 #define MAX_FS_KHZ                              16
 #define MAX_API_FS_KHZ                          48
diff --git a/silk/enc_API.c b/silk/enc_API.c
index 701c290..55a33f3 100644
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -82,7 +82,7 @@
     silk_memset( psEnc, 0, sizeof( silk_encoder ) );
     for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
         if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
-            silk_assert( 0 );
+            celt_assert( 0 );
         }
     }
 
@@ -91,7 +91,7 @@
 
     /* Read control structure */
     if( ret += silk_QueryEncoder( encState, encStatus ) ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
     }
 
     return ret;
@@ -144,7 +144,8 @@
     opus_int                        nSamplesIn,         /* I    Number of samples in input vector               */
     ec_enc                          *psRangeEnc,        /* I/O  Compressor data structure                       */
     opus_int32                      *nBytesOut,         /* I/O  Number of bytes in payload (input: Max bytes)   */
-    const opus_int                  prefillFlag         /* I    Flag to indicate prefilling buffers no coding   */
+    const opus_int                  prefillFlag,        /* I    Flag to indicate prefilling buffers no coding   */
+    opus_int                        activity            /* I    Decision of Opus voice activity detector        */
 )
 {
     opus_int   n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
@@ -166,7 +167,7 @@
 
     /* Check values in encoder control structure */
     if( ( ret = check_control_input( encControl ) ) != 0 ) {
-        silk_assert( 0 );
+        celt_assert( 0 );
         RESTORE_STACK;
         return ret;
     }
@@ -199,16 +200,26 @@
     tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
     curr_block = 0;
     if( prefillFlag ) {
+        silk_LP_state save_LP;
         /* Only accept input length of 10 ms */
         if( nBlocksOf10ms != 1 ) {
-            silk_assert( 0 );
+            celt_assert( 0 );
             RESTORE_STACK;
             return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
         }
+        if ( prefillFlag == 2 ) {
+            save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP;
+            /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */
+            save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
+        }
         /* Reset Encoder */
         for( n = 0; n < encControl->nChannelsInternal; n++ ) {
             ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
-            silk_assert( !ret );
+            /* Restore the variable LP state. */
+            if ( prefillFlag == 2 ) {
+                psEnc->state_Fxx[ n ].sCmn.sLP = save_LP;
+            }
+            celt_assert( !ret );
         }
         tmp_payloadSize_ms = encControl->payloadSize_ms;
         encControl->payloadSize_ms = 10;
@@ -221,13 +232,13 @@
     } else {
         /* Only accept input lengths that are a multiple of 10 ms */
         if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
-            silk_assert( 0 );
+            celt_assert( 0 );
             RESTORE_STACK;
             return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
         }
         /* Make sure no more than one packet can be produced */
         if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
-            silk_assert( 0 );
+            celt_assert( 0 );
             RESTORE_STACK;
             return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
         }
@@ -248,7 +259,7 @@
         }
         psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
     }
-    silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
+    celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
 
     /* Input buffering/resampling and encoding */
     nSamplesToBufferMax =
@@ -306,7 +317,7 @@
             }
             psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
         } else {
-            silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
+            celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
             silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
             ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
                 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
@@ -322,8 +333,8 @@
         /* Silk encoder */
         if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
             /* Enough data in input buffer, so encode */
-            silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
-            silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
+            celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
+            celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
 
             /* Deal with LBRR data */
             if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
@@ -425,7 +436,7 @@
                         psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16      = 65536;
                         psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
                     }
-                    silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] );
+                    silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity );
                 } else {
                     psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
                 }
@@ -440,7 +451,7 @@
                 silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
                 silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
             }
-            silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] );
+            silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity );
 
             /* Encode */
             for( n = 0; n < encControl->nChannelsInternal; n++ ) {
diff --git a/silk/encode_indices.c b/silk/encode_indices.c
index 666c8c0..4bcbc33 100644
--- a/silk/encode_indices.c
+++ b/silk/encode_indices.c
@@ -56,8 +56,8 @@
     /* Encode signal type and quantizer offset */
     /*******************************************/
     typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType;
-    silk_assert( typeOffset >= 0 && typeOffset < 6 );
-    silk_assert( encode_LBRR == 0 || typeOffset >= 2 );
+    celt_assert( typeOffset >= 0 && typeOffset < 6 );
+    celt_assert( encode_LBRR == 0 || typeOffset >= 2 );
     if( encode_LBRR || typeOffset >= 2 ) {
         ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 );
     } else {
@@ -90,7 +90,7 @@
     /****************/
     ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 );
     silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] );
-    silk_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
+    celt_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
     for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) {
         if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) {
             ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
diff --git a/silk/encode_pulses.c b/silk/encode_pulses.c
index ab00264..8a19991 100644
--- a/silk/encode_pulses.c
+++ b/silk/encode_pulses.c
@@ -86,7 +86,7 @@
     silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
     iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
     if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
-        silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
+        celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
         iter++;
         silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8));
     }
diff --git a/silk/fixed/apply_sine_window_FIX.c b/silk/fixed/apply_sine_window_FIX.c
index 4502b71..03e088a 100644
--- a/silk/fixed/apply_sine_window_FIX.c
+++ b/silk/fixed/apply_sine_window_FIX.c
@@ -57,15 +57,15 @@
     opus_int   k, f_Q16, c_Q16;
     opus_int32 S0_Q16, S1_Q16;
 
-    silk_assert( win_type == 1 || win_type == 2 );
+    celt_assert( win_type == 1 || win_type == 2 );
 
     /* Length must be in a range from 16 to 120 and a multiple of 4 */
-    silk_assert( length >= 16 && length <= 120 );
-    silk_assert( ( length & 3 ) == 0 );
+    celt_assert( length >= 16 && length <= 120 );
+    celt_assert( ( length & 3 ) == 0 );
 
     /* Frequency */
     k = ( length >> 2 ) - 4;
-    silk_assert( k >= 0 && k <= 26 );
+    celt_assert( k >= 0 && k <= 26 );
     f_Q16 = (opus_int)freq_table_Q16[ k ];
 
     /* Factor used for cosine approximation */
diff --git a/silk/fixed/burg_modified_FIX.c b/silk/fixed/burg_modified_FIX.c
index 80edbdf..274d4b2 100644
--- a/silk/fixed/burg_modified_FIX.c
+++ b/silk/fixed/burg_modified_FIX.c
@@ -65,7 +65,7 @@
     opus_int32       xcorr[ SILK_MAX_ORDER_LPC ];
     opus_int64       C0_64;
 
-    silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+    celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
 
     /* Compute autocorrelations, added over subframes */
     C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );
diff --git a/silk/fixed/encode_frame_FIX.c b/silk/fixed/encode_frame_FIX.c
index 4f9e086..a02bf87 100644
--- a/silk/fixed/encode_frame_FIX.c
+++ b/silk/fixed/encode_frame_FIX.c
@@ -43,21 +43,28 @@
 );
 
 void silk_encode_do_VAD_FIX(
-    silk_encoder_state_FIX          *psEnc                                  /* I/O  Pointer to Silk FIX encoder state                                           */
+    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
+    opus_int                        activity                                /* I    Decision of Opus voice activity detector                                    */
 )
 {
+    const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
+
     /****************************/
     /* Voice Activity Detection */
     /****************************/
     silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
+    /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
+    if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
+        psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
+    }
 
     /**************************************************/
     /* Convert speech activity into VAD and DTX flags */
     /**************************************************/
-    if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
+    if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
         psEnc->sCmn.noSpeechCounter++;
-        if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
+        if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
             psEnc->sCmn.inDTX = 0;
         } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
             psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
@@ -255,7 +262,7 @@
                 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
                     /* Restore output state from earlier iteration that did meet the bitrate budget */
                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
-                    silk_assert( sRangeEnc_copy2.offs <= 1275 );
+                    celt_assert( sRangeEnc_copy2.offs <= 1275 );
                     silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
                     psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
@@ -283,7 +290,7 @@
                     gainsID_lower = gainsID;
                     /* Copy part of the output state */
                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
-                    silk_assert( psRangeEnc->offs <= 1275 );
+                    celt_assert( psRangeEnc->offs <= 1275 );
                     silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
                     silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
                     LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
diff --git a/silk/fixed/find_LPC_FIX.c b/silk/fixed/find_LPC_FIX.c
index e55b63a..c762a0f 100644
--- a/silk/fixed/find_LPC_FIX.c
+++ b/silk/fixed/find_LPC_FIX.c
@@ -146,6 +146,6 @@
         silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
     }
 
-    silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
+    celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
     RESTORE_STACK;
 }
diff --git a/silk/fixed/find_pitch_lags_FIX.c b/silk/fixed/find_pitch_lags_FIX.c
index 9303e9d..6c3379f 100644
--- a/silk/fixed/find_pitch_lags_FIX.c
+++ b/silk/fixed/find_pitch_lags_FIX.c
@@ -59,7 +59,7 @@
     buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
 
     /* Safety check */
-    silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
+    celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
 
     /*************************************/
     /* Estimate LPC AR coefficients      */
diff --git a/silk/fixed/find_pred_coefs_FIX.c b/silk/fixed/find_pred_coefs_FIX.c
index 24c6aab..606d863 100644
--- a/silk/fixed/find_pred_coefs_FIX.c
+++ b/silk/fixed/find_pred_coefs_FIX.c
@@ -80,7 +80,7 @@
         /**********/
         /* VOICED */
         /**********/
-        silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
+        celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
 
         ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
         ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
diff --git a/silk/fixed/main_FIX.h b/silk/fixed/main_FIX.h
index 780afa3..6d2112e 100644
--- a/silk/fixed/main_FIX.h
+++ b/silk/fixed/main_FIX.h
@@ -66,7 +66,8 @@
 
 /* Encoder main function */
 void silk_encode_do_VAD_FIX(
-    silk_encoder_state_FIX          *psEnc                                  /* I/O  Pointer to Silk FIX encoder state                                           */
+    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
+    opus_int                        activity                                /* I    Decision of Opus voice activity detector                                    */
 );
 
 /* Encoder main function */
diff --git a/silk/fixed/pitch_analysis_core_FIX.c b/silk/fixed/pitch_analysis_core_FIX.c
index 8df109e..1472904 100644
--- a/silk/fixed/pitch_analysis_core_FIX.c
+++ b/silk/fixed/pitch_analysis_core_FIX.c
@@ -122,11 +122,11 @@
     SAVE_STACK;
 
     /* Check for valid sampling frequency */
-    silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
+    celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
 
     /* Check for valid complexity setting */
-    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
-    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+    celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
+    celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
 
     silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
     silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );
@@ -164,7 +164,7 @@
         silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
         frame_8kHz = frame_8kHz_buf;
     } else {
-        silk_assert( Fs_kHz == 8 );
+        celt_assert( Fs_kHz == 8 );
         frame_8kHz = frame;
     }
 
@@ -188,14 +188,14 @@
     target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ];
     for( k = 0; k < nb_subfr >> 1; k++ ) {
         /* Check that we are within range of the array */
-        silk_assert( target_ptr >= frame_4kHz );
-        silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
+        celt_assert( target_ptr >= frame_4kHz );
+        celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
 
         basis_ptr = target_ptr - MIN_LAG_4KHZ;
 
         /* Check that we are within range of the array */
-        silk_assert( basis_ptr >= frame_4kHz );
-        silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
+        celt_assert( basis_ptr >= frame_4kHz );
+        celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
 
         celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );
 
@@ -249,7 +249,7 @@
 
     /* Sort */
     length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
-    silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
+    celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
     silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
                                           length_d_srch );
 
@@ -274,7 +274,7 @@
             break;
         }
     }
-    silk_assert( length_d_srch > 0 );
+    celt_assert( length_d_srch > 0 );
 
     ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
     for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
@@ -325,8 +325,8 @@
     for( k = 0; k < nb_subfr; k++ ) {
 
         /* Check that we are within range of the array */
-        silk_assert( target_ptr >= frame_8kHz );
-        silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
+        celt_assert( target_ptr >= frame_8kHz );
+        celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
 
         energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );
         for( j = 0; j < length_d_comp; j++ ) {
@@ -550,7 +550,7 @@
         *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
         *contourIndex = (opus_int8)CBimax;
     }
-    silk_assert( *lagIndex >= 0 );
+    celt_assert( *lagIndex >= 0 );
     /* return as voiced */
     RESTORE_STACK;
     return 0;
@@ -587,8 +587,8 @@
     const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
     SAVE_STACK;
 
-    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
-    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+    celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
+    celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
 
     if( nb_subfr == PE_MAX_NB_SUBFR ) {
         Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -596,7 +596,7 @@
         nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
         cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     } else {
-        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+        celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
         Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
         Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
@@ -612,7 +612,7 @@
         /* Calculate the correlations for each subframe */
         lag_low  = matrix_ptr( Lag_range_ptr, k, 0, 2 );
         lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
-        silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
+        celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
         celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );
         for( j = lag_low; j <= lag_high; j++ ) {
             silk_assert( lag_counter < SCRATCH_SIZE );
@@ -659,8 +659,8 @@
     const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
     SAVE_STACK;
 
-    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
-    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+    celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
+    celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
 
     if( nb_subfr == PE_MAX_NB_SUBFR ) {
         Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -668,7 +668,7 @@
         nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
         cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     } else {
-        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+        celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
         Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
         Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
diff --git a/silk/fixed/residual_energy16_FIX.c b/silk/fixed/residual_energy16_FIX.c
index ebffb2a..7f130f3 100644
--- a/silk/fixed/residual_energy16_FIX.c
+++ b/silk/fixed/residual_energy16_FIX.c
@@ -47,10 +47,10 @@
     const opus_int32 *pRow;
 
     /* Safety checks */
-    silk_assert( D >=  0 );
-    silk_assert( D <= 16 );
-    silk_assert( cQ >  0 );
-    silk_assert( cQ < 16 );
+    celt_assert( D >=  0 );
+    celt_assert( D <= 16 );
+    celt_assert( cQ >  0 );
+    celt_assert( cQ < 16 );
 
     lshifts = 16 - cQ;
     Qxtra = lshifts;
diff --git a/silk/fixed/residual_energy_FIX.c b/silk/fixed/residual_energy_FIX.c
index 41f7477..6c7cade 100644
--- a/silk/fixed/residual_energy_FIX.c
+++ b/silk/fixed/residual_energy_FIX.c
@@ -58,7 +58,7 @@
 
     /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
     ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );
-    silk_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
+    celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
     for( i = 0; i < nb_subfr >> 1; i++ ) {
         /* Calculate half frame LPC residual signal including preceding samples */
         silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );
diff --git a/silk/fixed/schur64_FIX.c b/silk/fixed/schur64_FIX.c
index b2cb12d..4b7e19e 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 >= 0 && order <= SILK_MAX_ORDER_LPC );
+    celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
 
     /* Check for invalid input */
     if( c[ 0 ] <= 0 ) {
diff --git a/silk/fixed/schur_FIX.c b/silk/fixed/schur_FIX.c
index 59d44a6..2840f6b 100644
--- a/silk/fixed/schur_FIX.c
+++ b/silk/fixed/schur_FIX.c
@@ -43,7 +43,7 @@
     opus_int32    C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
     opus_int32    Ctmp1, Ctmp2, rc_tmp_Q15;
 
-    silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
+    celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
 
     /* Get number of leading zeros */
     lz = silk_CLZ32( c[ 0 ] );
diff --git a/silk/fixed/warped_autocorrelation_FIX.c b/silk/fixed/warped_autocorrelation_FIX.c
index 994c299..52002a1 100644
--- a/silk/fixed/warped_autocorrelation_FIX.c
+++ b/silk/fixed/warped_autocorrelation_FIX.c
@@ -52,7 +52,7 @@
     opus_int64 corr_QC[  MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
 
     /* Order must be even */
-    silk_assert( ( order & 1 ) == 0 );
+    celt_assert( ( order & 1 ) == 0 );
     silk_assert( 2 * QS - QC >= 0 );
 
     /* Loop over samples */
diff --git a/silk/fixed/x86/burg_modified_FIX_sse.c b/silk/fixed/x86/burg_modified_FIX_sse4_1.c
similarity index 99%
rename from silk/fixed/x86/burg_modified_FIX_sse.c
rename to silk/fixed/x86/burg_modified_FIX_sse4_1.c
index 3c3583c..bbb1ce0 100644
--- a/silk/fixed/x86/burg_modified_FIX_sse.c
+++ b/silk/fixed/x86/burg_modified_FIX_sse4_1.c
@@ -72,7 +72,7 @@
     __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
     __m128i CONST1 = _mm_set1_epi32(1);
 
-    silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+    celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
 
     /* Compute autocorrelations, added over subframes */
     silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
diff --git a/silk/fixed/x86/prefilter_FIX_sse.c b/silk/fixed/x86/prefilter_FIX_sse.c
index d8c9c2f..555432c 100644
--- a/silk/fixed/x86/prefilter_FIX_sse.c
+++ b/silk/fixed/x86/prefilter_FIX_sse.c
@@ -49,7 +49,7 @@
     opus_int32   acc_Q11, tmp1, tmp2;
 
     /* Order must be even */
-    silk_assert( ( order & 1 ) == 0 );
+    celt_assert( ( order & 1 ) == 0 );
 
     if (order == 10)
     {
@@ -65,7 +65,7 @@
             register opus_int32 state_8, state_9, state_a;
             register opus_int64 coef_Q13_8, coef_Q13_9;
 
-            silk_assert( length > 0 );
+            celt_assert( length > 0 );
 
             coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );
             coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );
diff --git a/silk/fixed/x86/vector_ops_FIX_sse.c b/silk/fixed/x86/vector_ops_FIX_sse4_1.c
similarity index 100%
rename from silk/fixed/x86/vector_ops_FIX_sse.c
rename to silk/fixed/x86/vector_ops_FIX_sse4_1.c
diff --git a/silk/float/LPC_analysis_filter_FLP.c b/silk/float/LPC_analysis_filter_FLP.c
index cae89a0..0e1a1fe 100644
--- a/silk/float/LPC_analysis_filter_FLP.c
+++ b/silk/float/LPC_analysis_filter_FLP.c
@@ -215,7 +215,7 @@
     const opus_int                  Order                               /* I    LPC order                                   */
 )
 {
-    silk_assert( Order <= length );
+    celt_assert( Order <= length );
 
     switch( Order ) {
         case 6:
@@ -239,7 +239,7 @@
         break;
 
         default:
-            silk_assert( 0 );
+            celt_assert( 0 );
         break;
     }
 
diff --git a/silk/float/apply_sine_window_FLP.c b/silk/float/apply_sine_window_FLP.c
index 6aae57c..e49e717 100644
--- a/silk/float/apply_sine_window_FLP.c
+++ b/silk/float/apply_sine_window_FLP.c
@@ -45,10 +45,10 @@
     opus_int   k;
     silk_float freq, c, S0, S1;
 
-    silk_assert( win_type == 1 || win_type == 2 );
+    celt_assert( win_type == 1 || win_type == 2 );
 
     /* Length must be multiple of 4 */
-    silk_assert( ( length & 3 ) == 0 );
+    celt_assert( ( length & 3 ) == 0 );
 
     freq = PI / ( length + 1 );
 
diff --git a/silk/float/burg_modified_FLP.c b/silk/float/burg_modified_FLP.c
index ea5dc25..756b76a 100644
--- a/silk/float/burg_modified_FLP.c
+++ b/silk/float/burg_modified_FLP.c
@@ -52,7 +52,7 @@
     double           CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
     double           Af[ SILK_MAX_ORDER_LPC ];
 
-    silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+    celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
 
     /* Compute autocorrelations, added over subframes */
     C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
diff --git a/silk/float/encode_frame_FLP.c b/silk/float/encode_frame_FLP.c
index c3ad50a..b029c3f 100644
--- a/silk/float/encode_frame_FLP.c
+++ b/silk/float/encode_frame_FLP.c
@@ -42,21 +42,28 @@
 );
 
 void silk_encode_do_VAD_FLP(
-    silk_encoder_state_FLP          *psEnc                              /* I/O  Encoder state FLP                           */
+    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
+    opus_int                        activity                            /* I    Decision of Opus voice activity detector    */
 )
 {
+    const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
+
     /****************************/
     /* Voice Activity Detection */
     /****************************/
     silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
+    /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
+    if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
+        psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
+    }
 
     /**************************************************/
     /* Convert speech activity into VAD and DTX flags */
     /**************************************************/
-    if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
+    if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
         psEnc->sCmn.noSpeechCounter++;
-        if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
+        if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
             psEnc->sCmn.inDTX = 0;
         } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
             psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
@@ -241,7 +248,7 @@
                 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
                     /* Restore output state from earlier iteration that did meet the bitrate budget */
                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
-                    silk_assert( sRangeEnc_copy2.offs <= 1275 );
+                    celt_assert( sRangeEnc_copy2.offs <= 1275 );
                     silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
                     psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
@@ -271,7 +278,7 @@
                     gainsID_lower = gainsID;
                     /* Copy part of the output state */
                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
-                    silk_assert( psRangeEnc->offs <= 1275 );
+                    celt_assert( psRangeEnc->offs <= 1275 );
                     silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
                     silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
                     LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
diff --git a/silk/float/find_LPC_FLP.c b/silk/float/find_LPC_FLP.c
index 4d63964..fa3ffe7 100644
--- a/silk/float/find_LPC_FLP.c
+++ b/silk/float/find_LPC_FLP.c
@@ -99,6 +99,6 @@
         silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
     }
 
-    silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
+    celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
         ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
 }
diff --git a/silk/float/find_pitch_lags_FLP.c b/silk/float/find_pitch_lags_FLP.c
index f3b22d2..dedbcd2 100644
--- a/silk/float/find_pitch_lags_FLP.c
+++ b/silk/float/find_pitch_lags_FLP.c
@@ -56,7 +56,7 @@
     buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
 
     /* Safety check */
-    silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
+    celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
 
     x_buf = x - psEnc->sCmn.ltp_mem_length;
 
diff --git a/silk/float/find_pred_coefs_FLP.c b/silk/float/find_pred_coefs_FLP.c
index cb2e763..dcf7c52 100644
--- a/silk/float/find_pred_coefs_FLP.c
+++ b/silk/float/find_pred_coefs_FLP.c
@@ -59,7 +59,7 @@
         /**********/
         /* VOICED */
         /**********/
-        silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
+        celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
 
         /* LTP analysis */
         silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
diff --git a/silk/float/main_FLP.h b/silk/float/main_FLP.h
index f47fc93..5dc0ccf 100644
--- a/silk/float/main_FLP.h
+++ b/silk/float/main_FLP.h
@@ -56,7 +56,8 @@
 
 /* Encoder main function */
 void silk_encode_do_VAD_FLP(
-    silk_encoder_state_FLP          *psEnc                              /* I/O  Encoder state FLP                           */
+    silk_encoder_state_FLP          *psEnc,                             /* I/O  Encoder state FLP                           */
+    opus_int                        activity                            /* I    Decision of Opus voice activity detector    */
 );
 
 /* Encoder main function */
diff --git a/silk/float/pitch_analysis_core_FLP.c b/silk/float/pitch_analysis_core_FLP.c
index b371693..f351bc3 100644
--- a/silk/float/pitch_analysis_core_FLP.c
+++ b/silk/float/pitch_analysis_core_FLP.c
@@ -109,11 +109,11 @@
     const opus_int8 *Lag_CB_ptr;
 
     /* Check for valid sampling frequency */
-    silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
+    celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
 
     /* Check for valid complexity setting */
-    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
-    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+    celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
+    celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
 
     silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
     silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
@@ -148,7 +148,7 @@
         silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );
         silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
     } else {
-        silk_assert( Fs_kHz == 8 );
+        celt_assert( Fs_kHz == 8 );
         silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );
     }
 
@@ -169,14 +169,14 @@
     target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
     for( k = 0; k < nb_subfr >> 1; k++ ) {
         /* Check that we are within range of the array */
-        silk_assert( target_ptr >= frame_4kHz );
-        silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+        celt_assert( target_ptr >= frame_4kHz );
+        celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
 
         basis_ptr = target_ptr - min_lag_4kHz;
 
         /* Check that we are within range of the array */
-        silk_assert( basis_ptr >= frame_4kHz );
-        silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+        celt_assert( basis_ptr >= frame_4kHz );
+        celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
 
         celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );
 
@@ -215,7 +215,7 @@
 
     /* Sort */
     length_d_srch = 4 + 2 * complexity;
-    silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
+    celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
     silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
 
     /* Escape if correlation is very low already here */
@@ -238,7 +238,7 @@
             break;
         }
     }
-    silk_assert( length_d_srch > 0 );
+    celt_assert( length_d_srch > 0 );
 
     for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
         d_comp[ i ] = 0;
@@ -471,7 +471,7 @@
         *lagIndex = (opus_int16)( lag - min_lag_8kHz );
         *contourIndex = (opus_int8)CBimax;
     }
-    silk_assert( *lagIndex >= 0 );
+    celt_assert( *lagIndex >= 0 );
     /* return as voiced */
     return 0;
 }
@@ -506,8 +506,8 @@
     opus_val32 xcorr[ SCRATCH_SIZE ];
     const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
 
-    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
-    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+    celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
+    celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
 
     if( nb_subfr == PE_MAX_NB_SUBFR ) {
         Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -515,7 +515,7 @@
         nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
         cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     } else {
-        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+        celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
         Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
         Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
@@ -572,8 +572,8 @@
     silk_float scratch_mem[ SCRATCH_SIZE ];
     const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
 
-    silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
-    silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
+    celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
+    celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
 
     if( nb_subfr == PE_MAX_NB_SUBFR ) {
         Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -581,7 +581,7 @@
         nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
         cbk_size      = PE_NB_CBKS_STAGE3_MAX;
     } else {
-        silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+        celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
         Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
         Lag_CB_ptr    = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
diff --git a/silk/float/residual_energy_FLP.c b/silk/float/residual_energy_FLP.c
index b2e03a8..1bd07b3 100644
--- a/silk/float/residual_energy_FLP.c
+++ b/silk/float/residual_energy_FLP.c
@@ -47,7 +47,7 @@
     silk_float tmp, nrg = 0.0f, regularization;
 
     /* Safety checks */
-    silk_assert( D >= 0 );
+    celt_assert( D >= 0 );
 
     regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] );
     for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) {
diff --git a/silk/float/schur_FLP.c b/silk/float/schur_FLP.c
index c1e0bbb..8526c74 100644
--- a/silk/float/schur_FLP.c
+++ b/silk/float/schur_FLP.c
@@ -41,7 +41,7 @@
     double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
     double Ctmp1, Ctmp2, rc_tmp;
 
-    silk_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
+    celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
 
     /* Copy correlations */
     k = 0;
diff --git a/silk/float/sort_FLP.c b/silk/float/sort_FLP.c
index f08d759..0e18f31 100644
--- a/silk/float/sort_FLP.c
+++ b/silk/float/sort_FLP.c
@@ -47,9 +47,9 @@
     opus_int   i, j;
 
     /* Safety checks */
-    silk_assert( K >  0 );
-    silk_assert( L >  0 );
-    silk_assert( L >= K );
+    celt_assert( K >  0 );
+    celt_assert( L >  0 );
+    celt_assert( L >= K );
 
     /* Write start indices in index vector */
     for( i = 0; i < K; i++ ) {
diff --git a/silk/float/warped_autocorrelation_FLP.c b/silk/float/warped_autocorrelation_FLP.c
index 542414f..9666276 100644
--- a/silk/float/warped_autocorrelation_FLP.c
+++ b/silk/float/warped_autocorrelation_FLP.c
@@ -46,7 +46,7 @@
     double      C[     MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
     /* Order must be even */
-    silk_assert( ( order & 1 ) == 0 );
+    celt_assert( ( order & 1 ) == 0 );
 
     /* Loop over samples */
     for( n = 0; n < length; n++ ) {
diff --git a/silk/interpolate.c b/silk/interpolate.c
index 1bd8ca4..833c28e 100644
--- a/silk/interpolate.c
+++ b/silk/interpolate.c
@@ -42,8 +42,8 @@
 {
     opus_int i;
 
-    silk_assert( ifact_Q2 >= 0 );
-    silk_assert( ifact_Q2 <= 4 );
+    celt_assert( ifact_Q2 >= 0 );
+    celt_assert( ifact_Q2 <= 4 );
 
     for( i = 0; i < d; i++ ) {
         xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );
diff --git a/silk/process_NLSFs.c b/silk/process_NLSFs.c
index 2f10f8d..d130809 100644
--- a/silk/process_NLSFs.c
+++ b/silk/process_NLSFs.c
@@ -48,7 +48,7 @@
 
     silk_assert( psEncC->speech_activity_Q8 >=   0 );
     silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
-    silk_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
+    celt_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
 
     /***********************/
     /* Calculate mu values */
@@ -60,7 +60,7 @@
         NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
     }
 
-    silk_assert( NLSF_mu_Q20 >  0 );
+    celt_assert( NLSF_mu_Q20 >  0 );
     silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) );
 
     /* Calculate NLSF weights */
@@ -101,7 +101,7 @@
 
     } else {
         /* Copy LPC coefficients for first half from second half */
-        silk_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
+        celt_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
         silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );
     }
 }
diff --git a/silk/resampler.c b/silk/resampler.c
index 374fbb3..1f11e50 100644
--- a/silk/resampler.c
+++ b/silk/resampler.c
@@ -91,14 +91,14 @@
     if( forEnc ) {
         if( ( Fs_Hz_in  != 8000 && Fs_Hz_in  != 12000 && Fs_Hz_in  != 16000 && Fs_Hz_in  != 24000 && Fs_Hz_in  != 48000 ) ||
             ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
-            silk_assert( 0 );
+            celt_assert( 0 );
             return -1;
         }
         S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
     } else {
         if( ( Fs_Hz_in  != 8000 && Fs_Hz_in  != 12000 && Fs_Hz_in  != 16000 ) ||
             ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
-            silk_assert( 0 );
+            celt_assert( 0 );
             return -1;
         }
         S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
@@ -151,7 +151,7 @@
             S->Coefs = silk_Resampler_1_6_COEFS;
         } else {
             /* None available */
-            silk_assert( 0 );
+            celt_assert( 0 );
             return -1;
         }
     } else {
@@ -181,9 +181,9 @@
     opus_int nSamples;
 
     /* Need at least 1 ms of input data */
-    silk_assert( inLen >= S->Fs_in_kHz );
+    celt_assert( inLen >= S->Fs_in_kHz );
     /* Delay can't exceed the 1 ms of buffering */
-    silk_assert( S->inputDelay <= S->Fs_in_kHz );
+    celt_assert( S->inputDelay <= S->Fs_in_kHz );
 
     nSamples = S->Fs_in_kHz - S->inputDelay;
 
diff --git a/silk/resampler_down2.c b/silk/resampler_down2.c
index cec3634..971d7bf 100644
--- a/silk/resampler_down2.c
+++ b/silk/resampler_down2.c
@@ -43,8 +43,8 @@
     opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 );
     opus_int32 in32, out32, Y, X;
 
-    silk_assert( silk_resampler_down2_0 > 0 );
-    silk_assert( silk_resampler_down2_1 < 0 );
+    celt_assert( silk_resampler_down2_0 > 0 );
+    celt_assert( silk_resampler_down2_1 < 0 );
 
     /* Internal variables and state are in Q10 format */
     for( k = 0; k < len2; k++ ) {
diff --git a/silk/resampler_private_down_FIR.c b/silk/resampler_private_down_FIR.c
index 783e42b..3e8735a 100644
--- a/silk/resampler_private_down_FIR.c
+++ b/silk/resampler_private_down_FIR.c
@@ -136,7 +136,7 @@
             }
             break;
         default:
-            silk_assert( 0 );
+            celt_assert( 0 );
     }
     return out;
 }
diff --git a/silk/sort.c b/silk/sort.c
index 7187c9e..4fba16f 100644
--- a/silk/sort.c
+++ b/silk/sort.c
@@ -48,9 +48,9 @@
     opus_int        i, j;
 
     /* Safety checks */
-    silk_assert( K >  0 );
-    silk_assert( L >  0 );
-    silk_assert( L >= K );
+    celt_assert( K >  0 );
+    celt_assert( L >  0 );
+    celt_assert( L >= K );
 
     /* Write start indices in index vector */
     for( i = 0; i < K; i++ ) {
@@ -96,9 +96,9 @@
     opus_int value;
 
     /* Safety checks */
-    silk_assert( K >  0 );
-    silk_assert( L >  0 );
-    silk_assert( L >= K );
+    celt_assert( K >  0 );
+    celt_assert( L >  0 );
+    celt_assert( L >= K );
 
     /* Write start indices in index vector */
     for( i = 0; i < K; i++ ) {
@@ -141,7 +141,7 @@
     opus_int    i, j;
 
     /* Safety checks */
-    silk_assert( L >  0 );
+    celt_assert( L >  0 );
 
     /* Sort vector elements by value, increasing order */
     for( i = 1; i < L; i++ ) {
diff --git a/silk/stereo_LR_to_MS.c b/silk/stereo_LR_to_MS.c
index dda0298..c822666 100644
--- a/silk/stereo_LR_to_MS.c
+++ b/silk/stereo_LR_to_MS.c
@@ -109,7 +109,7 @@
     if( total_rate_bps < 1 ) {
         total_rate_bps = 1;
     }
-    min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 );
+    min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 );
     silk_assert( min_mid_rate_bps < 32767 );
     /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
     frac_3_Q16 = silk_MUL( 3, frac_Q16 );
diff --git a/silk/stereo_encode_pred.c b/silk/stereo_encode_pred.c
index e6dd195..03becb6 100644
--- a/silk/stereo_encode_pred.c
+++ b/silk/stereo_encode_pred.c
@@ -41,11 +41,11 @@
 
     /* Entropy coding */
     n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ];
-    silk_assert( n < 25 );
+    celt_assert( n < 25 );
     ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 );
     for( n = 0; n < 2; n++ ) {
-        silk_assert( ix[ n ][ 0 ] < 3 );
-        silk_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
+        celt_assert( ix[ n ][ 0 ] < 3 );
+        celt_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
         ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 );
         ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 );
     }
diff --git a/silk/structs.h b/silk/structs.h
index 4ff590b..3380c75 100644
--- a/silk/structs.h
+++ b/silk/structs.h
@@ -78,6 +78,7 @@
     opus_int32                   In_LP_State[ 2 ];           /* Low pass filter state */
     opus_int32                   transition_frame_no;        /* Counter which is mapped to a cut-off frequency */
     opus_int                     mode;                       /* Operating mode, <0: switch down, >0: switch up; 0: do nothing           */
+    opus_int32                   saved_fs_kHz;               /* If non-zero, holds the last sampling rate before a bandwidth switching reset. */
 } silk_LP_state;
 
 /* Structure containing NLSF codebook */
diff --git a/silk/tables.h b/silk/tables.h
index 8b0380e..95230c4 100644
--- a/silk/tables.h
+++ b/silk/tables.h
@@ -97,12 +97,6 @@
 extern const silk_NLSF_CB_struct silk_NLSF_CB_WB;                                                   /* 1040 */
 extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB;                                                /* 728 */
 
-/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
-extern const opus_int32  silk_TargetRate_table_NB[  TARGET_RATE_TAB_SZ ];                           /*  32 */
-extern const opus_int32  silk_TargetRate_table_MB[  TARGET_RATE_TAB_SZ ];                           /*  32 */
-extern const opus_int32  silk_TargetRate_table_WB[  TARGET_RATE_TAB_SZ ];                           /*  32 */
-extern const opus_int16  silk_SNR_table_Q1[         TARGET_RATE_TAB_SZ ];                           /*  32 */
-
 /* Quantization offsets */
 extern const opus_int16  silk_Quantization_Offsets_Q10[ 2 ][ 2 ];                                   /*   8 */
 
diff --git a/silk/tables_other.c b/silk/tables_other.c
index 398686b..e34d907 100644
--- a/silk/tables_other.c
+++ b/silk/tables_other.c
@@ -38,20 +38,6 @@
 {
 #endif
 
-/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
-const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {
-    0,      8000,   9400,   11500,  13500,  17500,  25000,  MAX_TARGET_RATE_BPS
-};
-const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {
-    0,      9000,   12000,  14500,  18500,  24500,  35500,  MAX_TARGET_RATE_BPS
-};
-const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {
-    0,      10500,  14000,  17000,  21500,  28500,  42000,  MAX_TARGET_RATE_BPS
-};
-const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {
-    18,     29,     38,     40,     46,     52,     62,     84
-};
-
 /* Tables for stereo predictor coding */
 const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {
     -13732, -10050, -8266, -7526, -6500, -5000, -2950,  -820,
diff --git a/silk/x86/NSQ_del_dec_sse.c b/silk/x86/NSQ_del_dec_sse4_1.c
similarity index 99%
rename from silk/x86/NSQ_del_dec_sse.c
rename to silk/x86/NSQ_del_dec_sse4_1.c
index c5212be..2c75ede 100644
--- a/silk/x86/NSQ_del_dec_sse.c
+++ b/silk/x86/NSQ_del_dec_sse4_1.c
@@ -247,7 +247,7 @@
 
                 /* Rewhiten with new A coefs */
                 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
-                silk_assert( start_idx > 0 );
+                celt_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 );
@@ -353,7 +353,7 @@
     __m128i b_Q12_0123, b_sr_Q12_0123;
     SAVE_STACK;
 
-    silk_assert( nStatesDelayedDecision > 0 );
+    celt_assert( nStatesDelayedDecision > 0 );
     ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
 
     shp_lag_ptr  = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
diff --git a/silk/x86/NSQ_sse.c b/silk/x86/NSQ_sse4_1.c
similarity index 99%
rename from silk/x86/NSQ_sse.c
rename to silk/x86/NSQ_sse4_1.c
index 6a9e6e9..b0315e3 100644
--- a/silk/x86/NSQ_sse.c
+++ b/silk/x86/NSQ_sse4_1.c
@@ -199,7 +199,7 @@
             if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
                 /* Rewhiten with new A coefs */
                 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
-                silk_assert( start_idx > 0 );
+                celt_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 );
diff --git a/silk/x86/VAD_sse.c b/silk/x86/VAD_sse4_1.c
similarity index 98%
rename from silk/x86/VAD_sse.c
rename to silk/x86/VAD_sse4_1.c
index 4e90f44..d02ddf4 100644
--- a/silk/x86/VAD_sse.c
+++ b/silk/x86/VAD_sse4_1.c
@@ -65,9 +65,9 @@
 
     /* Safety checks */
     silk_assert( VAD_N_BANDS == 4 );
-    silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
-    silk_assert( psEncC->frame_length <= 512 );
-    silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
+    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
+    celt_assert( psEncC->frame_length <= 512 );
+    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
 
     /***********************/
     /* Filter and Decimate */
diff --git a/silk/x86/VQ_WMat_EC_sse.c b/silk/x86/VQ_WMat_EC_sse4_1.c
similarity index 100%
rename from silk/x86/VQ_WMat_EC_sse.c
rename to silk/x86/VQ_WMat_EC_sse4_1.c
diff --git a/silk_sources.mk b/silk_sources.mk
index 6d14392..67c8a4f 100644
--- a/silk_sources.mk
+++ b/silk_sources.mk
@@ -77,11 +77,11 @@
 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 \
+SILK_SOURCES_SSE4_1 = silk/x86/NSQ_sse4_1.c \
+silk/x86/NSQ_del_dec_sse4_1.c \
 silk/x86/x86_silk_map.c \
-silk/x86/VAD_sse.c \
-silk/x86/VQ_WMat_EC_sse.c
+silk/x86/VAD_sse4_1.c \
+silk/x86/VQ_WMat_EC_sse4_1.c
 
 SILK_SOURCES_ARM_NEON_INTR = \
 silk/arm/arm_silk_map.c \
@@ -115,8 +115,8 @@
 silk/fixed/schur64_FIX.c \
 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_SOURCES_FIXED_SSE4_1 = silk/fixed/x86/vector_ops_FIX_sse4_1.c \
+silk/fixed/x86/burg_modified_FIX_sse4_1.c
 
 SILK_SOURCES_FIXED_ARM_NEON_INTR = \
 silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
diff --git a/src/analysis.c b/src/analysis.c
index f4160e4..b192ae4 100644
--- a/src/analysis.c
+++ b/src/analysis.c
@@ -50,6 +50,8 @@
 
 #ifndef DISABLE_FLOAT_API
 
+#define TRANSITION_PENALTY 10
+
 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,
@@ -224,19 +226,23 @@
   /* 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)
 {
    int pos;
    int curr_lookahead;
-   float psum;
    float tonality_max;
    float tonality_avg;
    int tonality_count;
    int i;
+   int pos0;
+   float prob_avg;
+   float prob_count;
+   float prob_min, prob_max;
+   float vad_prob;
+   int mpos, vpos;
+   int bandwidth_span;
 
    pos = tonal->read_pos;
    curr_lookahead = tonal->write_pos-tonal->read_pos;
@@ -254,9 +260,12 @@
       pos--;
    if (pos<0)
       pos = DETECT_SIZE-1;
+   pos0 = pos;
    OPUS_COPY(info_out, &tonal->info[pos], 1);
    tonality_max = tonality_avg = info_out->tonality;
    tonality_count = 1;
+   /* Look at the neighbouring frames and pick largest bandwidth found (to be safe). */
+   bandwidth_span = 6;
    /* If possible, look ahead for a tone to compensate for the delay in the tone detector. */
    for (i=0;i<3;i++)
    {
@@ -268,8 +277,122 @@
       tonality_max = MAX32(tonality_max, tonal->info[pos].tonality);
       tonality_avg += tonal->info[pos].tonality;
       tonality_count++;
+      info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth);
+      bandwidth_span--;
+   }
+   pos = pos0;
+   /* Look back in time to see if any has a wider bandwidth than the current frame. */
+   for (i=0;i<bandwidth_span;i++)
+   {
+      pos--;
+      if (pos < 0)
+         pos = DETECT_SIZE-1;
+      if (pos == tonal->write_pos)
+         break;
+      info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth);
    }
    info_out->tonality = MAX32(tonality_avg/tonality_count, tonality_max-.2f);
+
+   mpos = vpos = pos0;
+   /* If we have enough look-ahead, compensate for the ~5-frame delay in the music prob and
+      ~1 frame delay in the VAD prob. */
+   if (curr_lookahead > 15)
+   {
+      mpos += 5;
+      if (mpos>=DETECT_SIZE)
+         mpos -= DETECT_SIZE;
+      vpos += 1;
+      if (vpos>=DETECT_SIZE)
+         vpos -= DETECT_SIZE;
+   }
+
+   /* The following calculations attempt to minimize a "badness function"
+      for the transition. When switching from speech to music, the badness
+      of switching at frame k is
+      b_k = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T)
+      where
+      v_i is the activity probability (VAD) at frame i,
+      p_i is the music probability at frame i
+      T is the probability threshold for switching
+      S is the penalty for switching during active audio rather than silence
+      the current frame has index i=0
+
+      Rather than apply badness to directly decide when to switch, what we compute
+      instead is the threshold for which the optimal switching point is now. When
+      considering whether to switch now (frame 0) or at frame k, we have:
+      S*v_0 = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T)
+      which gives us:
+      T = ( \sum_{i=0}^{k-1} v_i*p_i + S*(v_k-v_0) ) / ( \sum_{i=0}^{k-1} v_i )
+      We take the min threshold across all positive values of k (up to the maximum
+      amount of lookahead we have) to give us the threshold for which the current
+      frame is the optimal switch point.
+
+      The last step is that we need to consider whether we want to switch at all.
+      For that we use the average of the music probability over the entire window.
+      If the threshold is higher than that average we're not going to
+      switch, so we compute a min with the average as well. The result of all these
+      min operations is music_prob_min, which gives the threshold for switching to music
+      if we're currently encoding for speech.
+
+      We do the exact opposite to compute music_prob_max which is used for switching
+      from music to speech.
+    */
+   prob_min = 1.f;
+   prob_max = 0.f;
+   vad_prob = tonal->info[vpos].activity_probability;
+   prob_count = MAX16(.1f, vad_prob);
+   prob_avg = MAX16(.1f, vad_prob)*tonal->info[mpos].music_prob;
+   while (1)
+   {
+      float pos_vad;
+      mpos++;
+      if (mpos==DETECT_SIZE)
+         mpos = 0;
+      if (mpos == tonal->write_pos)
+         break;
+      vpos++;
+      if (vpos==DETECT_SIZE)
+         vpos = 0;
+      if (vpos == tonal->write_pos)
+         break;
+      pos_vad = tonal->info[vpos].activity_probability;
+      prob_min = MIN16((prob_avg - TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_min);
+      prob_max = MAX16((prob_avg + TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_max);
+      prob_count += MAX16(.1f, pos_vad);
+      prob_avg += MAX16(.1f, pos_vad)*tonal->info[mpos].music_prob;
+   }
+   info_out->music_prob = prob_avg/prob_count;
+   prob_min = MIN16(prob_avg/prob_count, prob_min);
+   prob_max = MAX16(prob_avg/prob_count, prob_max);
+   prob_min = MAX16(prob_min, 0.f);
+   prob_max = MIN16(prob_max, 1.f);
+
+   /* If we don't have enough look-ahead, do our best to make a decent decision. */
+   if (curr_lookahead < 10)
+   {
+      float pmin, pmax;
+      pmin = prob_min;
+      pmax = prob_max;
+      pos = pos0;
+      /* Look for min/max in the past. */
+      for (i=0;i<IMIN(tonal->count-1, 15);i++)
+      {
+         pos--;
+         if (pos < 0)
+            pos = DETECT_SIZE-1;
+         pmin = MIN16(pmin, tonal->info[pos].music_prob);
+         pmax = MAX16(pmax, tonal->info[pos].music_prob);
+      }
+      /* Bias against switching on active audio. */
+      pmin = MAX16(0.f, pmin - .1f*vad_prob);
+      pmax = MIN16(1.f, pmax + .1f*vad_prob);
+      prob_min += (1.f-.1f*curr_lookahead)*(pmin - prob_min);
+      prob_max += (1.f-.1f*curr_lookahead)*(pmax - prob_max);
+   }
+   info_out->music_prob_min = prob_min;
+   info_out->music_prob_max = prob_max;
+
+   /* printf("%f %f %f %f %f\n", prob_min, prob_max, prob_avg/prob_count, vad_prob, info_out->music_prob); */
    tonal->read_subframe += len/(tonal->Fs/400);
    while (tonal->read_subframe>=8)
    {
@@ -278,21 +401,6 @@
    }
    if (tonal->read_pos>=DETECT_SIZE)
       tonal->read_pos-=DETECT_SIZE;
-
-   /* 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
-      time (DETECT_SIZE-curr_lookahead-1) */
-   for (i=0;i<DETECT_SIZE-curr_lookahead;i++)
-      psum += tonal->pmusic[i];
-   for (;i<DETECT_SIZE;i++)
-      psum += tonal->pspeech[i];
-   psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;
-   /*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] = {
@@ -340,6 +448,7 @@
     float alpha, alphaE, alphaE2;
     float frame_loudness;
     float bandwidth_mask;
+    int is_masked[NB_TBANDS+1];
     int bandwidth=0;
     float maxE = 0;
     float noise_floor;
@@ -352,11 +461,16 @@
     float band_log2[NB_TBANDS+1];
     float leakage_from[NB_TBANDS+1];
     float leakage_to[NB_TBANDS+1];
+    float layer_out[MAX_NEURONS];
+    float below_max_pitch;
+    float above_max_pitch;
     SAVE_STACK;
 
     alpha = 1.f/IMIN(10, 1+tonal->count);
     alphaE = 1.f/IMIN(25, 1+tonal->count);
-    alphaE2 = 1.f/IMIN(500, 1+tonal->count);
+    /* Noise floor related decay for bandwidth detection: -2.2 dB/second */
+    alphaE2 = 1.f/IMIN(100, 1+tonal->count);
+    if (tonal->count <= 1) alphaE2 = 1;
 
     if (tonal->Fs == 48000)
     {
@@ -368,12 +482,6 @@
        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;
@@ -632,9 +740,12 @@
     maxE = 0;
     noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
     noise_floor *= noise_floor;
+    below_max_pitch=0;
+    above_max_pitch=0;
     for (b=0;b<NB_TBANDS;b++)
     {
        float E=0;
+       float Em;
        int band_start, band_end;
        /* Keep a margin of 300 Hz for aliasing */
        band_start = tbands[b];
@@ -647,41 +758,59 @@
        }
        E = SCALE_ENER(E);
        maxE = MAX32(maxE, E);
+       if (band_start < 64)
+       {
+          below_max_pitch += E;
+       } else {
+          above_max_pitch += 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);
+       Em = MAX32(E, tonal->meanE[b]);
        /* Consider the band "active" only if all these conditions are met:
-          1) less than 10 dB below the simple follower
-          2) less than 90 dB below the peak band (maximal masking possible considering
+          1) 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
+          2) 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))
+       if (E*1e9f > maxE && (Em > 3*noise_floor*(band_end-band_start) || E > noise_floor*(band_end-band_start)))
           bandwidth = b+1;
+       /* Check if the band is masked (see below). */
+       is_masked[b] = E < (tonal->prev_bandwidth >= b+1  ? .01f : .05f)*bandwidth_mask;
+       /* Use a simple follower with 13 dB/Bark slope for spreading function. */
+       bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
     }
     /* Special case for the last two bands, for which we don't have spectrum but only
-       the energy above 12 kHz. */
+       the energy above 12 kHz. The difficulty here is that the high-pass we use
+       leaks some LF energy, so we need to increase the threshold without accidentally cutting
+       off the band. */
     if (tonal->Fs == 48000) {
-       float ratio;
-       float E = hp_ener*(1.f/(240*240));
-       ratio = tonal->prev_bandwidth==20 ? 0.03f : 0.07f;
+       float noise_ratio;
+       float Em;
+       float E = hp_ener*(1.f/(60*60));
+       noise_ratio = tonal->prev_bandwidth==20 ? 10.f : 30.f;
+
 #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);
+       above_max_pitch += 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)
+       Em = MAX32(E, tonal->meanE[b]);
+       if (Em > 3*noise_ratio*noise_floor*160 || E > noise_ratio*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;
+       /* Check if the band is masked (see below). */
+       is_masked[b] = E < (tonal->prev_bandwidth == 20  ? .01f : .05f)*bandwidth_mask;
     }
+    if (above_max_pitch > below_max_pitch)
+       info->max_pitch_ratio = below_max_pitch/above_max_pitch;
+    else
+       info->max_pitch_ratio = 1;
+    /* In some cases, resampling aliasing can create a small amount of energy in the first band
+       being cut. So if the last band is masked, we don't include it.  */
+    if (bandwidth == 20 && is_masked[NB_TBANDS])
+       bandwidth-=2;
+    else if (bandwidth > 0 && bandwidth <= NB_TBANDS && is_masked[bandwidth-1])
+       bandwidth--;
     if (tonal->count<=2)
        bandwidth = 20;
     frame_loudness = 20*(float)log10(frame_loudness);
@@ -761,139 +890,15 @@
     features[23] = info->tonality_slope + 0.069216f;
     features[24] = tonal->lowECount - 0.067930f;
 
-    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);*/
-    /* Probability of active audio (as opposed to silence) */
-    frame_probs[1] = .5f*frame_probs[1]+.5f;
-    frame_probs[1] *= frame_probs[1];
+    compute_dense(&layer0, layer_out, features);
+    compute_gru(&layer1, tonal->rnn_state, layer_out);
+    compute_dense(&layer2, frame_probs, tonal->rnn_state);
 
     /* Probability of speech or music vs noise */
     info->activity_probability = frame_probs[1];
+    info->music_prob = frame_probs[0];
 
-    /*printf("%f %f\n", frame_probs[0], frame_probs[1]);*/
-    {
-       /* Probability of state transition */
-       float tau;
-       /* Represents independence of the MLP probabilities, where
-          beta=1 means fully independent. */
-       float beta;
-       /* Denormalized probability of speech (p0) and music (p1) after update */
-       float p0, p1;
-       /* Probabilities for "all speech" and "all music" */
-       float s0, m0;
-       /* Probability sum for renormalisation */
-       float psum;
-       /* Instantaneous probability of speech and music, with beta pre-applied. */
-       float speech0;
-       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 = .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 = .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->music_prob)*(1-tau) +    tonal->music_prob *tau;
-       p1 =    tonal->music_prob *(1-tau) + (1-tonal->music_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[0], beta);
-       p1 *= (float)pow(frame_probs[0], beta);
-       /* Normalise the probabilities to get the Marokv probability of music. */
-       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. */
-       speech0 = (float)pow(1-frame_probs[0], beta);
-       music0  = (float)pow(frame_probs[0], beta);
-       if (tonal->count==1)
-       {
-          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. */
-       s0 = tonal->pspeech[0] + tonal->pspeech[1];
-       m0 = tonal->pmusic [0] + tonal->pmusic [1];
-       /* Updates s0 and m0 with instantaneous probability. */
-       tonal->pspeech[0] = s0*(1-tau)*speech0;
-       tonal->pmusic [0] = m0*(1-tau)*music0;
-       /* Propagate the transition probabilities */
-       for (i=1;i<DETECT_SIZE-1;i++)
-       {
-          tonal->pspeech[i] = tonal->pspeech[i+1]*speech0;
-          tonal->pmusic [i] = tonal->pmusic [i+1]*music0;
-       }
-       /* Probability that the latest frame is speech, when all the previous ones were music. */
-       tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0;
-       /* Probability that the latest frame is music, when all the previous ones were speech. */
-       tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0;
-
-       /* Renormalise probabilities to 1 */
-       for (i=0;i<DETECT_SIZE;i++)
-          psum += tonal->pspeech[i] + tonal->pmusic[i];
-       psum = 1.f/psum;
-       for (i=0;i<DETECT_SIZE;i++)
-       {
-          tonal->pspeech[i] *= psum;
-          tonal->pmusic [i] *= psum;
-       }
-       psum = tonal->pmusic[0];
-       for (i=1;i<DETECT_SIZE;i++)
-          psum += tonal->pspeech[i];
-
-       /* Estimate our confidence in the speech/music decisions */
-       if (frame_probs[1]>.75)
-       {
-          if (tonal->music_prob>.9)
-          {
-             float adapt;
-             adapt = 1.f/(++tonal->music_confidence_count);
-             tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500);
-             tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence);
-          }
-          if (tonal->music_prob<.1)
-          {
-             float adapt;
-             adapt = 1.f/(++tonal->speech_confidence_count);
-             tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);
-             tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);
-          }
-       }
-    }
-    tonal->last_music = tonal->music_prob>.5f;
+    /*printf("%f %f %f\n", frame_probs[0], frame_probs[1], info->music_prob);*/
 #ifdef MLP_TRAINING
     for (i=0;i<25;i++)
        printf("%f ", features[i]);
diff --git a/src/analysis.h b/src/analysis.h
index cac51df..289c845 100644
--- a/src/analysis.h
+++ b/src/analysis.h
@@ -30,6 +30,7 @@
 
 #include "celt.h"
 #include "opus_private.h"
+#include "mlp.h"
 
 #define NB_FRAMES 8
 #define NB_TBANDS 18
@@ -64,28 +65,16 @@
    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 count;
    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. */
-   float pspeech[DETECT_SIZE];
-   /** Probability of having music for time i to DETECT_SIZE-1 (and speech before).
-       pmusic[0] is the probability that all frames in the window are music. */
-   float pmusic[DETECT_SIZE];
-   float speech_confidence;
-   float music_confidence;
-   int speech_confidence_count;
-   int music_confidence_count;
    int write_pos;
    int read_pos;
    int read_subframe;
    float hp_ener_accum;
+   float rnn_state[MAX_NEURONS];
    opus_val32 downmix_state[3];
    AnalysisInfo info[DETECT_SIZE];
 } TonalityAnalysisState;
diff --git a/src/mapping_matrix.c b/src/mapping_matrix.c
new file mode 100644
index 0000000..31298af
--- /dev/null
+++ b/src/mapping_matrix.c
@@ -0,0 +1,378 @@
+/* Copyright (c) 2017 Google Inc.
+   Written by Andrew Allen */
+/*
+   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 "arch.h"
+#include "float_cast.h"
+#include "opus_private.h"
+#include "opus_defines.h"
+#include "mapping_matrix.h"
+
+#define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row)
+
+opus_int32 mapping_matrix_get_size(int rows, int cols)
+{
+  opus_int32 size;
+
+  /* Mapping Matrix must only support up to 255 channels in or out.
+   * Additionally, the total cell count must be <= 65004 octets in order
+   * for the matrix to be stored in an OGG header.
+   */
+  if (rows > 255 || cols > 255)
+      return 0;
+  size = rows * (opus_int32)cols * sizeof(opus_int16);
+  if (size > 65004)
+    return 0;
+
+  return align(sizeof(MappingMatrix)) + align(size);
+}
+
+opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix)
+{
+  /* void* cast avoids clang -Wcast-align warning */
+  return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix)));
+}
+
+void mapping_matrix_init(MappingMatrix * const matrix,
+  int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size)
+{
+  int i;
+  opus_int16 *ptr;
+
+#if !defined(ENABLE_ASSERTIONS)
+  (void)data_size;
+#endif
+  celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16)));
+
+  matrix->rows = rows;
+  matrix->cols = cols;
+  matrix->gain = gain;
+  ptr = mapping_matrix_get_data(matrix);
+  for (i = 0; i < rows * cols; i++)
+  {
+     ptr[i] = data[i];
+  }
+}
+
+#ifndef DISABLE_FLOAT_API
+void mapping_matrix_multiply_channel_in_float(
+    const MappingMatrix *matrix,
+    const float *input,
+    int input_rows,
+    opus_val16 *output,
+    int output_row,
+    int output_rows,
+    int frame_size)
+{
+  /* Matrix data is ordered col-wise. */
+  opus_int16* matrix_data;
+  int i, col;
+
+  celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
+
+  matrix_data = mapping_matrix_get_data(matrix);
+
+  for (i = 0; i < frame_size; i++)
+  {
+    float tmp = 0;
+    for (col = 0; col < input_rows; col++)
+    {
+      tmp +=
+        matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
+        input[MATRIX_INDEX(input_rows, col, i)];
+    }
+#if defined(FIXED_POINT)
+    output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp);
+#else
+    output[output_rows * i] = (1/32768.f)*tmp;
+#endif
+  }
+}
+
+void mapping_matrix_multiply_channel_out_float(
+    const MappingMatrix *matrix,
+    const opus_val16 *input,
+    int input_row,
+    int input_rows,
+    float *output,
+    int output_rows,
+    int frame_size
+)
+{
+  /* Matrix data is ordered col-wise. */
+  opus_int16* matrix_data;
+  int i, row;
+  float input_sample;
+
+  celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
+
+  matrix_data = mapping_matrix_get_data(matrix);
+
+  for (i = 0; i < frame_size; i++)
+  {
+#if defined(FIXED_POINT)
+    input_sample = (1/32768.f)*input[input_rows * i];
+#else
+    input_sample = input[input_rows * i];
+#endif
+    for (row = 0; row < output_rows; row++)
+    {
+      float tmp =
+        (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
+        input_sample;
+      output[MATRIX_INDEX(output_rows, row, i)] += tmp;
+    }
+  }
+}
+#endif /* DISABLE_FLOAT_API */
+
+void mapping_matrix_multiply_channel_in_short(
+    const MappingMatrix *matrix,
+    const opus_int16 *input,
+    int input_rows,
+    opus_val16 *output,
+    int output_row,
+    int output_rows,
+    int frame_size)
+{
+  /* Matrix data is ordered col-wise. */
+  opus_int16* matrix_data;
+  int i, col;
+
+  celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
+
+  matrix_data = mapping_matrix_get_data(matrix);
+
+  for (i = 0; i < frame_size; i++)
+  {
+    opus_val32 tmp = 0;
+    for (col = 0; col < input_rows; col++)
+    {
+#if defined(FIXED_POINT)
+      tmp +=
+        ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
+        (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8;
+#else
+      tmp +=
+        matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
+        input[MATRIX_INDEX(input_rows, col, i)];
+#endif
+    }
+#if defined(FIXED_POINT)
+    output[output_rows * i] = (opus_int16)((tmp + 64) >> 7);
+#else
+    output[output_rows * i] = (1/(32768.f*32768.f))*tmp;
+#endif
+  }
+}
+
+void mapping_matrix_multiply_channel_out_short(
+    const MappingMatrix *matrix,
+    const opus_val16 *input,
+    int input_row,
+    int input_rows,
+    opus_int16 *output,
+    int output_rows,
+    int frame_size)
+{
+  /* Matrix data is ordered col-wise. */
+  opus_int16* matrix_data;
+  int i, row;
+  opus_int32 input_sample;
+
+  celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
+
+  matrix_data = mapping_matrix_get_data(matrix);
+
+  for (i = 0; i < frame_size; i++)
+  {
+#if defined(FIXED_POINT)
+    input_sample = (opus_int32)input[input_rows * i];
+#else
+    input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]);
+#endif
+    for (row = 0; row < output_rows; row++)
+    {
+      opus_int32 tmp =
+        (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
+        input_sample;
+      output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15;
+    }
+  }
+}
+
+const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 };
+const opus_int16 mapping_matrix_foa_mixing_data[36] = {
+     16384,      0, -16384,  23170,      0,      0,  16384,  23170,
+     16384,      0,      0,      0,  16384,      0, -16384, -23170,
+         0,      0,  16384, -23170,  16384,      0,      0,      0,
+         0,      0,      0,      0,  32767,      0,      0,      0,
+         0,      0,      0,  32767
+};
+
+const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 };
+const opus_int16 mapping_matrix_soa_mixing_data[121] = {
+     10923,   7723,  13377, -13377,  11585,   9459,   7723, -16384,
+     -6689,      0,      0,  10923,   7723,  13377,  13377, -11585,
+      9459,   7723,  16384,  -6689,      0,      0,  10923, -15447,
+     13377,      0,      0, -18919,   7723,      0,  13377,      0,
+         0,  10923,   7723, -13377, -13377,  11585,  -9459,   7723,
+     16384,  -6689,      0,      0,  10923,  -7723,      0,  13377,
+    -16384,      0, -15447,      0,   9459,      0,      0,  10923,
+     -7723,      0, -13377,  16384,      0, -15447,      0,   9459,
+         0,      0,  10923,  15447,      0,      0,      0,      0,
+    -15447,      0, -18919,      0,      0,  10923,   7723, -13377,
+     13377, -11585,  -9459,   7723, -16384,  -6689,      0,      0,
+     10923, -15447, -13377,      0,      0,  18919,   7723,      0,
+     13377,      0,      0,      0,      0,      0,      0,      0,
+         0,      0,      0,      0,  32767,      0,      0,      0,
+         0,      0,      0,      0,      0,      0,      0,      0,
+     32767
+};
+
+const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 };
+const opus_int16 mapping_matrix_toa_mixing_data[324] = {
+      8208,      0,   -881,  14369,      0,      0,  -8192,  -4163,
+     13218,      0,      0,      0,  11095,  -8836,  -6218,  14833,
+         0,      0,   8208, -10161,    881,  10161, -13218,  -2944,
+     -8192,   2944,      0, -10488,  -6218,   6248, -11095,  -6248,
+         0, -10488,      0,      0,   8208,  10161,    881, -10161,
+    -13218,   2944,  -8192,  -2944,      0,  10488,  -6218,  -6248,
+    -11095,   6248,      0,  10488,      0,      0,   8176,   5566,
+    -11552,   5566,   9681, -11205,   8192, -11205,      0,   4920,
+    -15158,   9756,  -3334,   9756,      0,  -4920,      0,      0,
+      8176,   7871,  11552,      0,      0,  15846,   8192,      0,
+     -9681,  -6958,      0,  13797,   3334,      0, -15158,      0,
+         0,      0,   8176,      0,  11552,   7871,      0,      0,
+      8192,  15846,   9681,      0,      0,      0,   3334,  13797,
+     15158,   6958,      0,      0,   8176,   5566, -11552,  -5566,
+     -9681, -11205,   8192,  11205,      0,   4920,  15158,   9756,
+     -3334,  -9756,      0,   4920,      0,      0,   8208,  14369,
+      -881,      0,      0,  -4163,  -8192,      0, -13218, -14833,
+         0,  -8836,  11095,      0,   6218,      0,      0,      0,
+      8208,  10161,    881,  10161,  13218,   2944,  -8192,   2944,
+         0,  10488,   6218,  -6248, -11095,  -6248,      0, -10488,
+         0,      0,   8208, -14369,   -881,      0,      0,   4163,
+     -8192,      0, -13218,  14833,      0,   8836,  11095,      0,
+      6218,      0,      0,      0,   8208,      0,   -881, -14369,
+         0,      0,  -8192,   4163,  13218,      0,      0,      0,
+     11095,   8836,  -6218, -14833,      0,      0,   8176,  -5566,
+    -11552,   5566,  -9681,  11205,   8192, -11205,      0,  -4920,
+     15158,  -9756,  -3334,   9756,      0,  -4920,      0,      0,
+      8176,      0,  11552,  -7871,      0,      0,   8192, -15846,
+      9681,      0,      0,      0,   3334, -13797,  15158,  -6958,
+         0,      0,   8176,  -7871,  11552,      0,      0, -15846,
+      8192,      0,  -9681,   6958,      0, -13797,   3334,      0,
+    -15158,      0,      0,      0,   8176,  -5566, -11552,  -5566,
+      9681,  11205,   8192,  11205,      0,  -4920, -15158,  -9756,
+     -3334,  -9756,      0,   4920,      0,      0,   8208, -10161,
+       881, -10161,  13218,  -2944,  -8192,  -2944,      0, -10488,
+      6218,   6248, -11095,   6248,      0,  10488,      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,  32767
+};
+
+const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 };
+const opus_int16 mapping_matrix_foa_demixing_data[36] = {
+     16384,  16384,  16384,  16384,      0,      0,      0,  23170,
+         0, -23170,      0,      0, -16384,  16384, -16384,  16384,
+         0,      0,  23170,      0, -23170,      0,      0,      0,
+         0,      0,      0,      0,  32767,      0,      0,      0,
+         0,      0,      0,  32767
+};
+
+const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 };
+const opus_int16 mapping_matrix_soa_demixing_data[121] = {
+      2771,   2771,   2771,   2771,   2771,   2771,   2771,   2771,
+      2771,      0,      0,  10033,  10033, -20066,  10033,  14189,
+     14189, -28378,  10033, -20066,      0,      0,   3393,   3393,
+      3393,  -3393,      0,      0,      0,  -3393,  -3393,      0,
+         0, -17378,  17378,      0, -17378, -24576,  24576,      0,
+     17378,      0,      0,      0, -14189,  14189,      0, -14189,
+    -28378,  28378,      0,  14189,      0,      0,      0,   2399,
+      2399,  -4799,  -2399,      0,      0,      0,  -2399,   4799,
+         0,      0,   1959,   1959,   1959,   1959,  -3918,  -3918,
+     -3918,   1959,   1959,      0,      0,  -4156,   4156,      0,
+      4156,      0,      0,      0,  -4156,      0,      0,      0,
+      8192,   8192, -16384,   8192,  16384,  16384, -32768,   8192,
+    -16384,      0,      0,      0,      0,      0,      0,      0,
+         0,      0,      0,      0,   8312,      0,      0,      0,
+         0,      0,      0,      0,      0,      0,      0,      0,
+      8312
+};
+
+const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 };
+const opus_int16 mapping_matrix_toa_demixing_data[324] = {
+      8192,   8192,   8192,   8192,   8192,   8192,   8192,   8192,
+      8192,   8192,   8192,   8192,   8192,   8192,   8192,   8192,
+         0,      0,      0,  -9779,   9779,   6263,   8857,      0,
+      6263,  13829,   9779, -13829,      0,  -6263,      0,  -8857,
+     -6263,  -9779,      0,      0,  -3413,   3413,   3413, -11359,
+     11359,  11359, -11359,  -3413,   3413,  -3413,  -3413, -11359,
+     11359,  11359, -11359,   3413,      0,      0,  13829,   9779,
+     -9779,   6263,      0,   8857,  -6263,      0,   9779,      0,
+    -13829,   6263,  -8857,      0,  -6263,  -9779,      0,      0,
+         0, -15617, -15617,   6406,      0,      0,  -6406,      0,
+     15617,      0,      0,  -6406,      0,      0,   6406,  15617,
+         0,      0,      0,  -5003,   5003, -10664,  15081,      0,
+    -10664,  -7075,   5003,   7075,      0,  10664,      0, -15081,
+     10664,  -5003,      0,      0,  -8176,  -8176,  -8176,   8208,
+      8208,   8208,   8208,  -8176,  -8176,  -8176,  -8176,   8208,
+      8208,   8208,   8208,  -8176,      0,      0,  -7075,   5003,
+     -5003, -10664,      0,  15081,  10664,      0,   5003,      0,
+      7075, -10664, -15081,      0,  10664,  -5003,      0,      0,
+     15617,      0,      0,      0,  -6406,   6406,      0, -15617,
+         0, -15617,  15617,      0,   6406,  -6406,      0,      0,
+         0,      0,      0, -11393,  11393,   2993,  -4233,      0,
+      2993, -16112,  11393,  16112,      0,  -2993,      0,   4233,
+     -2993, -11393,      0,      0,      0,  -9974,  -9974, -13617,
+         0,      0,  13617,      0,   9974,      0,      0,  13617,
+         0,      0, -13617,   9974,      0,      0,      0,   5579,
+     -5579,  10185,  14403,      0,  10185,  -7890,  -5579,   7890,
+         0, -10185,      0, -14403, -10185,   5579,      0,      0,
+     11826, -11826, -11826,   -901,    901,    901,   -901,  11826,
+    -11826,  11826,  11826,   -901,    901,    901,   -901, -11826,
+         0,      0,  -7890,  -5579,   5579,  10185,      0,  14403,
+    -10185,      0,  -5579,      0,   7890,  10185, -14403,      0,
+    -10185,   5579,      0,      0,  -9974,      0,      0,      0,
+    -13617,  13617,      0,   9974,      0,   9974,  -9974,      0,
+     13617, -13617,      0,      0,      0,      0,  16112, -11393,
+     11393,  -2993,      0,   4233,   2993,      0, -11393,      0,
+    -16112,  -2993,  -4233,      0,   2993,  11393,      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,  32767
+};
+
diff --git a/src/mapping_matrix.h b/src/mapping_matrix.h
new file mode 100644
index 0000000..9c20483
--- /dev/null
+++ b/src/mapping_matrix.h
@@ -0,0 +1,133 @@
+/* Copyright (c) 2017 Google Inc.
+   Written by Andrew Allen */
+/*
+   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.
+*/
+
+/**
+ * @file mapping_matrix.h
+ * @brief Opus reference implementation mapping matrix API
+ */
+
+#ifndef MAPPING_MATRIX_H
+#define MAPPING_MATRIX_H
+
+#include "opus_types.h"
+#include "opus_projection.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct MappingMatrix
+{
+    int rows; /* number of channels outputted from matrix. */
+    int cols; /* number of channels inputted to matrix. */
+    int gain; /* in dB. S7.8-format. */
+    /* Matrix cell data goes here using col-wise ordering. */
+} MappingMatrix;
+
+opus_int32 mapping_matrix_get_size(int rows, int cols);
+
+opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix);
+
+void mapping_matrix_init(
+    MappingMatrix * const st,
+    int rows,
+    int cols,
+    int gain,
+    const opus_int16 *data,
+    opus_int32 data_size
+);
+
+#ifndef DISABLE_FLOAT_API
+void mapping_matrix_multiply_channel_in_float(
+    const MappingMatrix *matrix,
+    const float *input,
+    int input_rows,
+    opus_val16 *output,
+    int output_row,
+    int output_rows,
+    int frame_size
+);
+
+void mapping_matrix_multiply_channel_out_float(
+    const MappingMatrix *matrix,
+    const opus_val16 *input,
+    int input_row,
+    int input_rows,
+    float *output,
+    int output_rows,
+    int frame_size
+);
+#endif /* DISABLE_FLOAT_API */
+
+void mapping_matrix_multiply_channel_in_short(
+    const MappingMatrix *matrix,
+    const opus_int16 *input,
+    int input_rows,
+    opus_val16 *output,
+    int output_row,
+    int output_rows,
+    int frame_size
+);
+
+void mapping_matrix_multiply_channel_out_short(
+    const MappingMatrix *matrix,
+    const opus_val16 *input,
+    int input_row,
+    int input_rows,
+    opus_int16 *output,
+    int output_rows,
+    int frame_size
+);
+
+/* Pre-computed mixing and demixing matrices for 1st to 3rd-order ambisonics.
+ *   foa: first-order ambisonics
+ *   soa: second-order ambisonics
+ *   toa: third-order ambisonics
+ */
+extern const MappingMatrix mapping_matrix_foa_mixing;
+extern const opus_int16 mapping_matrix_foa_mixing_data[36];
+
+extern const MappingMatrix mapping_matrix_soa_mixing;
+extern const opus_int16 mapping_matrix_soa_mixing_data[121];
+
+extern const MappingMatrix mapping_matrix_toa_mixing;
+extern const opus_int16 mapping_matrix_toa_mixing_data[324];
+
+extern const MappingMatrix mapping_matrix_foa_demixing;
+extern const opus_int16 mapping_matrix_foa_demixing_data[36];
+
+extern const MappingMatrix mapping_matrix_soa_demixing;
+extern const opus_int16 mapping_matrix_soa_demixing_data[121];
+
+extern const MappingMatrix mapping_matrix_toa_demixing;
+extern const opus_int16 mapping_matrix_toa_demixing_data[324];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAPPING_MATRIX_H */
diff --git a/src/mlp.c b/src/mlp.c
index ff9e50d..f43a704 100644
--- a/src/mlp.c
+++ b/src/mlp.c
@@ -1,5 +1,5 @@
 /* Copyright (c) 2008-2011 Octasic Inc.
-   Written by Jean-Marc Valin */
+                 2012-2017 Jean-Marc Valin */
 /*
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
@@ -29,42 +29,13 @@
 #include "config.h"
 #endif
 
+#include <math.h>
 #include "opus_types.h"
 #include "opus_defines.h"
-
-#include <math.h>
-#include "mlp.h"
 #include "arch.h"
 #include "tansig_table.h"
-#define MAX_NEURONS 100
+#include "mlp.h"
 
-#if 0
-static OPUS_INLINE opus_val16 tansig_approx(opus_val32 _x) /* Q19 */
-{
-    int i;
-    opus_val16 xx; /* Q11 */
-    /*double x, y;*/
-    opus_val16 dy, yy; /* Q14 */
-    /*x = 1.9073e-06*_x;*/
-    if (_x>=QCONST32(8,19))
-        return QCONST32(1.,14);
-    if (_x<=-QCONST32(8,19))
-        return -QCONST32(1.,14);
-    xx = EXTRACT16(SHR32(_x, 8));
-    /*i = lrint(25*x);*/
-    i = SHR32(ADD32(1024,MULT16_16(25, xx)),11);
-    /*x -= .04*i;*/
-    xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8));
-    /*x = xx*(1./2048);*/
-    /*y = tansig_table[250+i];*/
-    yy = tansig_table[250+i];
-    /*y = yy*(1./16384);*/
-    dy = 16384-MULT16_16_Q14(yy,yy);
-    yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx)));
-    return yy;
-}
-#else
-/*extern const float tansig_table[501];*/
 static OPUS_INLINE float tansig_approx(float x)
 {
     int i;
@@ -92,54 +63,79 @@
     y = y + x*dy*(1 - y*x);
     return sign*y;
 }
-#endif
 
-#if 0
-void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out)
+static OPUS_INLINE float sigmoid_approx(float x)
 {
-    int j;
-    opus_val16 hidden[MAX_NEURONS];
-    const opus_val16 *W = m->weights;
-    /* Copy to tmp_in */
-    for (j=0;j<m->topo[1];j++)
-    {
-        int k;
-        opus_val32 sum = SHL32(EXTEND32(*W++),8);
-        for (k=0;k<m->topo[0];k++)
-            sum = MAC16_16(sum, in[k],*W++);
-        hidden[j] = tansig_approx(sum);
-    }
-    for (j=0;j<m->topo[2];j++)
-    {
-        int k;
-        opus_val32 sum = SHL32(EXTEND32(*W++),14);
-        for (k=0;k<m->topo[1];k++)
-            sum = MAC16_16(sum, hidden[k], *W++);
-        out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17)));
-    }
+   return .5f + .5f*tansig_approx(.5f*x);
 }
-#else
-void mlp_process(const MLP *m, const float *in, float *out)
+
+void compute_dense(const DenseLayer *layer, float *output, const float *input)
 {
-    int j;
-    float hidden[MAX_NEURONS];
-    const float *W = m->weights;
-    /* Copy to tmp_in */
-    for (j=0;j<m->topo[1];j++)
-    {
-        int k;
-        float sum = *W++;
-        for (k=0;k<m->topo[0];k++)
-            sum = sum + in[k]**W++;
-        hidden[j] = tansig_approx(sum);
-    }
-    for (j=0;j<m->topo[2];j++)
-    {
-        int k;
-        float sum = *W++;
-        for (k=0;k<m->topo[1];k++)
-            sum = sum + hidden[k]**W++;
-        out[j] = tansig_approx(sum);
-    }
+   int i, j;
+   int N, M;
+   int stride;
+   M = layer->nb_inputs;
+   N = layer->nb_neurons;
+   stride = N;
+   for (i=0;i<N;i++)
+   {
+      /* Compute update gate. */
+      float sum = layer->bias[i];
+      for (j=0;j<M;j++)
+         sum += layer->input_weights[j*stride + i]*input[j];
+      output[i] = WEIGHTS_SCALE*sum;
+   }
+   if (layer->sigmoid) {
+      for (i=0;i<N;i++)
+         output[i] = sigmoid_approx(output[i]);
+   } else {
+      for (i=0;i<N;i++)
+         output[i] = tansig_approx(output[i]);
+   }
 }
-#endif
+
+void compute_gru(const GRULayer *gru, float *state, const float *input)
+{
+   int i, j;
+   int N, M;
+   int stride;
+   float z[MAX_NEURONS];
+   float r[MAX_NEURONS];
+   float h[MAX_NEURONS];
+   M = gru->nb_inputs;
+   N = gru->nb_neurons;
+   stride = 3*N;
+   for (i=0;i<N;i++)
+   {
+      /* Compute update gate. */
+      float sum = gru->bias[i];
+      for (j=0;j<M;j++)
+         sum += gru->input_weights[j*stride + i]*input[j];
+      for (j=0;j<N;j++)
+         sum += gru->recurrent_weights[j*stride + i]*state[j];
+      z[i] = sigmoid_approx(WEIGHTS_SCALE*sum);
+   }
+   for (i=0;i<N;i++)
+   {
+      /* Compute reset gate. */
+      float sum = gru->bias[N + i];
+      for (j=0;j<M;j++)
+         sum += gru->input_weights[N + j*stride + i]*input[j];
+      for (j=0;j<N;j++)
+         sum += gru->recurrent_weights[N + j*stride + i]*state[j];
+      r[i] = sigmoid_approx(WEIGHTS_SCALE*sum);
+   }
+   for (i=0;i<N;i++)
+   {
+      /* Compute output. */
+      float sum = gru->bias[2*N + i];
+      for (j=0;j<M;j++)
+         sum += gru->input_weights[2*N + j*stride + i]*input[j];
+      for (j=0;j<N;j++)
+         sum += gru->recurrent_weights[2*N + j*stride + i]*state[j]*r[j];
+      h[i] = z[i]*state[i] + (1-z[i])*tansig_approx(WEIGHTS_SCALE*sum);
+   }
+   for (i=0;i<N;i++)
+      state[i] = h[i];
+}
+
diff --git a/src/mlp.h b/src/mlp.h
index 618e246..d767055 100644
--- a/src/mlp.h
+++ b/src/mlp.h
@@ -1,5 +1,4 @@
-/* Copyright (c) 2008-2011 Octasic Inc.
-   Written by Jean-Marc Valin */
+/* Copyright (c) 2017 Jean-Marc Valin */
 /*
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
@@ -28,16 +27,34 @@
 #ifndef _MLP_H_
 #define _MLP_H_
 
-#include "arch.h"
+#include "opus_types.h"
+
+#define WEIGHTS_SCALE (1.f/128)
+
+#define MAX_NEURONS 32
 
 typedef struct {
-    int layers;
-    const int *topo;
-    const float *weights;
-} MLP;
+  const opus_int8 *bias;
+  const opus_int8 *input_weights;
+  int nb_inputs;
+  int nb_neurons;
+  int sigmoid;
+} DenseLayer;
 
-extern const MLP net;
+typedef struct {
+  const opus_int8 *bias;
+  const opus_int8 *input_weights;
+  const opus_int8 *recurrent_weights;
+  int nb_inputs;
+  int nb_neurons;
+} GRULayer;
 
-void mlp_process(const MLP *m, const float *in, float *out);
+extern const DenseLayer layer0;
+extern const GRULayer layer1;
+extern const DenseLayer layer2;
+
+void compute_dense(const DenseLayer *layer, float *output, const float *input);
+
+void compute_gru(const GRULayer *gru, float *state, const float *input);
 
 #endif /* _MLP_H_ */
diff --git a/src/mlp_data.c b/src/mlp_data.c
index a819880..ae4178d 100644
--- a/src/mlp_data.c
+++ b/src/mlp_data.c
@@ -1,112 +1,672 @@
+/*This file is automatically generated from a Keras model*/
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #include "mlp.h"
 
-/* RMS error was 0.280492, seed was 1480478173 */
-/* 0.005976 0.031821 (0.280494 0.280492) done */
-
-static const float weights[450] = {
-
-/* hidden layer */
--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 */
-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, 16, 2};
-
-const MLP net = {
-    3,
-    topo,
-    weights
+static const opus_int8 layer0_weights[800] = {
+   -30, -9, 2, -12, 5, -1, 8, 9,
+   9, 8, -13, 18, -17, -34, -5, 17,
+   -11, 0, -4, 10, 2, 10, 15, -8,
+   2, -1, 0, 5, 13, -3, -16, 1,
+   -5, 3, 7, -28, -13, 6, 36, -3,
+   19, -60, -17, -28, 7, -11, -30, -7,
+   2, -42, -21, -3, 6, -22, 33, -9,
+   7, -30, 21, -14, 24, -11, -20, -18,
+   -5, -12, 12, -49, -50, -49, 16, 9,
+   -37, -1, 9, 34, -13, -31, -31, 12,
+   16, 44, -42, 2, -9, 8, -18, -6,
+   9, 36, 19, 11, 13, 12, -21, 3,
+   -28, -12, 3, 33, 25, -14, 11, 1,
+   -94, -39, 18, -12, -11, -15, -7, 49,
+   52, 10, -43, 9, 57, 8, 21, -6,
+   14, -15, 44, -8, 7, -30, -13, -2,
+   -9, 25, -2, -127, 18, -11, -52, 26,
+   -27, 27, 10, -10, 7, 43, 6, -24,
+   41, 10, -18, -27, 10, 17, 9, 10,
+   -17, -10, 20, -6, 22, 55, 35, -80,
+   36, 25, -24, -36, 15, 9, -19, 88,
+   19, 64, -51, -35, 17, 0, -7, 41,
+   -16, 27, 4, 15, -1, 18, -16, 47,
+   -39, -54, -8, 13, -25, -20, 102, -18,
+   -5, 44, 11, -28, 71, 2, -51, -5,
+   5, 2, -83, -9, -29, 8, 21, -53,
+   58, -37, -7, 13, 38, 9, 34, -1,
+   -41, 21, 4, -24, -36, -33, -21, 32,
+   75, -2, 1, -68, -1, 47, -29, 32,
+   20, 12, -65, -87, 5, 16, -12, 24,
+   40, 15, 7, 19, -26, -17, 17, 6,
+   -2, -37, -30, -9, 32, -127, -39, 0,
+   -31, -27, 4, -22, 23, -6, -77, 35,
+   -61, 32, -37, -24, 13, -11, -1, -40,
+   -3, 17, -7, 13, 11, 59, -19, 10,
+   6, -18, 0, 13, 3, -6, -23, 19,
+   11, -17, 13, -1, -80, 40, -53, 69,
+   -29, -54, 0, -4, 33, -25, -2, 38,
+   35, 36, -15, 46, 2, -13, -16, -8,
+   -8, 12, -24, -9, -55, -5, -9, 32,
+   11, 7, 12, -18, -10, -86, -38, 54,
+   37, -25, 18, -43, 7, -27, -27, -54,
+   13, 9, 22, 70, 6, 35, -7, 23,
+   -15, -44, -6, 7, -66, -85, 32, 40,
+   -19, -9, -7, 12, -15, 7, 2, 6,
+   -35, 11, 28, 0, 26, 14, 1, 1,
+   4, 12, 18, 35, 22, -18, -3, 14,
+   -1, 7, 14, -8, -14, -3, 4, -3,
+   -19, -7, -1, -25, -27, 25, -26, -2,
+   33, -22, -27, -25, 4, -9, 7, 21,
+   26, -30, 10, -9, -20, 11, 27, 10,
+   5, -18, 14, -4, 2, -17, -5, -7,
+   -9, -13, 15, 29, 1, -10, -16, -10,
+   35, 36, -7, -22, -44, 17, 30, 22,
+   21, -1, 22, -11, 32, -8, -7, 5,
+   -10, 5, 30, -20, 29, -20, -34, 12,
+   -4, -6, 6, -13, 10, -5, -68, -1,
+   24, 9, 19, -24, -64, 31, 19, 27,
+   -26, 75, -45, 41, 39, -42, 8, 6,
+   23, -30, 16, -25, 30, 34, 8, -38,
+   -3, 18, 16, -31, 22, -4, -9, 1,
+   20, 9, 38, -32, 0, -45, 0, -6,
+   -13, 11, -25, -32, -22, 31, -24, -11,
+   -11, -4, -4, 20, -34, 22, 20, 9,
+   -25, 27, -5, 28, -29, 29, 6, 21,
+   -6, -18, 54, 4, -46, 23, 21, -14,
+   -31, 36, -41, -24, 4, 22, 10, 11,
+   7, 36, -32, -13, -52, -17, 24, 28,
+   -37, -36, -1, 24, 9, -38, 35, 48,
+   18, 2, -1, 45, 10, 39, 24, -38,
+   13, 8, -16, 8, 25, 11, 7, -29,
+   -11, 7, 20, -30, -38, -45, 14, -18,
+   -28, -9, 65, 61, 22, -53, -38, -16,
+   36, 46, 20, -39, 32, -61, -6, -6,
+   -36, -33, -18, -28, 56, 101, 45, 11,
+   -28, -23, -29, -61, 20, -47, 2, 48,
+   27, -17, 1, 40, 1, 3, -51, 15,
+   35, 28, 22, 35, 53, -61, -29, 12,
+   -6, -21, 10, 3, -20, 2, -25, 1,
+   -6, 31, 11, -3, 1, -10, -52, 6,
+   126, -105, 122, 127, -128, 127, 127, -128,
+   127, 108, 12, 127, 48, -128, -36, -128,
+   127, 127, -128, -128, 127, 89, -128, 127,
+   -128, -128, -128, 127, 127, -128, -128, -93,
+   -82, 20, 125, 65, -82, 127, 38, -74,
+   81, 88, -88, 79, 51, -47, -111, -26,
+   14, 83, -88, -112, 24, 35, -101, 98,
+   -99, -48, -45, 46, 83, -60, -79, 45,
+   -20, -41, 9, 4, 52, 54, 93, -10,
+   4, 13, 3, 123, 6, 94, -111, -69,
+   -14, -31, 10, 12, 53, -79, -11, -21,
+   -2, -44, -72, 92, 65, -57, 56, -38,
+   127, -56, -128, 127, 127, -128, 86, 117,
+   -75, -128, 127, -19, -99, -112, 127, -128,
+   127, -48, 114, 118, -128, -128, 117, -17,
+   -6, 121, -128, 127, -128, 82, 54, -106,
+   127, 127, -33, 100, -39, -23, 18, -78,
+   -34, -29, -1, -30, 127, -26, 127, -128,
+   126, -128, 27, -23, -79, -120, -127, 127,
+   72, 66, 29, 7, -66, -56, -117, -128
 };
+
+static const opus_int8 layer0_bias[32] = {
+   51, -16, 1, 13, -5, -6, -16, -7,
+   11, -6, 106, 26, 28, -14, 21, -29,
+   7, 18, -18, -17, 21, -17, -9, 20,
+   -25, -3, -34, 48, 11, -13, -31, -20
+};
+
+static const opus_int8 layer1_weights[2304] = {
+   22, -1, -7, 7, 29, -27, -31, -17,
+   -13, 33, 44, -8, 11, 33, 24, 78,
+   15, 19, 30, -2, -24, 5, 49, 5,
+   36, 29, -14, -11, -48, -33, 21, -42,
+   -38, -12, 55, -37, 54, -8, 1, 36,
+   17, 0, 51, 31, 59, 7, -12, 53,
+   4, 32, -14, 48, 5, -10, -16, -8,
+   1, -16, -56, -24, -6, 18, -2, 23,
+   6, 46, -6, -10, 20, 35, -44, -15,
+   -49, 36, 16, 5, -7, -79, -67, 12,
+   70, -3, -79, -54, -85, -24, 47, -22,
+   33, 21, 69, -1, 11, 22, 14, -16,
+   -16, -22, -28, -11, 11, -41, 31, -26,
+   -33, -19, -4, 27, 32, -50, 5, -10,
+   -38, -22, -8, 35, -31, 1, -41, -15,
+   -11, 44, 28, -17, -41, -23, 17, 2,
+   -23, -26, -13, -13, -17, 6, 14, -31,
+   -25, 9, -19, 39, -8, 4, 31, -1,
+   -45, -11, -28, -92, -46, -15, 21, 118,
+   -22, 45, -51, 11, -20, -20, -15, 13,
+   -21, -97, -29, -32, -23, -42, 94, 1,
+   23, -8, 63, -3, -46, 19, -26, 32,
+   -40, -74, -26, 26, -4, -13, 30, -20,
+   -30, -25, -14, -31, -45, -43, 4, -60,
+   -48, -12, -34, 2, 2, 3, 13, 15,
+   11, 16, 5, 46, -9, -55, -16, -57,
+   29, 14, 38, -50, -2, -44, -11, -8,
+   52, -27, -38, -7, 20, 47, 17, -59,
+   0, 47, 46, -63, 35, -17, 19, 33,
+   68, -19, 2, 15, -16, 28, -16, -103,
+   26, -35, 47, -39, -60, 30, 31, -23,
+   -52, -13, 116, 47, -25, 30, 40, 30,
+   -22, 2, 12, -27, -18, 31, -10, 27,
+   -8, -66, 12, 14, 4, -26, -28, -13,
+   3, 13, -26, -51, 37, 5, 2, -21,
+   47, 3, 13, 25, -41, -27, -8, -4,
+   5, -76, -33, 28, 10, 9, -46, -74,
+   19, 28, 25, 31, 54, -55, 68, 38,
+   -24, -32, 2, 4, 68, 11, -1, 99,
+   5, 16, -2, -74, 40, 26, -26, 33,
+   31, -1, -68, 14, -6, 25, 9, 29,
+   60, 61, 7, -7, 0, -24, 7, 77,
+   4, -1, 16, -7, 13, -15, -19, 28,
+   -31, -24, -16, 37, 24, 13, 30, 10,
+   -30, 11, 11, -10, 22, 60, 28, 45,
+   -3, -40, -62, -5, -102, 9, -32, -27,
+   -54, 21, 15, -5, 37, -43, -11, 37,
+   -19, 47, -64, -128, -27, -114, 21, -66,
+   59, 46, -3, -12, -87, -9, 4, 19,
+   -113, -36, 78, 57, -26, -38, -77, -10,
+   6, 6, -75, 25, -97, -11, 33, -46,
+   1, 13, -21, -33, -20, 16, -6, -3,
+   -11, -4, -27, 38, 8, -41, -2, -33,
+   18, 19, -26, 1, -29, -22, -4, -14,
+   -55, -11, -80, -3, 11, 34, 90, 51,
+   11, 17, 43, 36, 127, -32, 29, 103,
+   9, 27, 13, 64, 56, 70, -14, 3,
+   -12, 10, 37, 3, 12, -22, -10, 46,
+   28, 10, 20, 26, -24, 18, 9, 7,
+   14, 34, -5, -7, 31, -14, -56, 11,
+   -18, -8, -17, -7, -10, -40, 10, -33,
+   -32, -43, 5, 9, 11, -4, 10, 50,
+   -12, -5, 46, 9, 7, 1, 11, 15,
+   91, -17, 7, -50, 23, 6, -30, -99,
+   0, -17, 14, 8, -10, -25, -30, -69,
+   -62, 31, 127, 114, -23, 101, -5, -54,
+   -6, -22, 7, -56, 39, 18, -29, 0,
+   46, 8, -79, 4, -21, 18, -32, 62,
+   -12, -8, -12, -58, 31, -32, 17, 6,
+   -24, 25, 24, 9, -4, -19, 45, 6,
+   17, -14, 5, -27, 16, -4, -41, 25,
+   -36, 5, 15, 12, 50, 27, 25, 23,
+   -44, -69, -9, -19, -48, -8, 4, 12,
+   -6, 13, -19, -30, -36, 26, 37, -1,
+   -3, -30, -42, -14, -10, -20, 26, -54,
+   -27, -44, 4, 73, -26, 90, 32, -69,
+   -29, -16, 3, 103, 15, -17, 37, 24,
+   -23, -31, 33, -37, -64, 25, 13, -81,
+   -28, -32, 27, 5, -35, -23, 15, -22,
+   19, -7, 9, 30, 19, -23, 27, -13,
+   43, 29, -29, -6, 9, -40, -33, -33,
+   -32, 9, 11, -48, -8, -23, -52, 46,
+   17, -22, -42, 35, -15, -41, 16, 34,
+   31, -42, -19, -11, 55, 7, -39, 89,
+   -11, -33, 20, -14, 22, 32, 3, -17,
+   -6, 14, 34, 1, 55, -21, -90, -8,
+   18, 27, 13, -29, 21, 15, -33, -51,
+   -9, -11, 4, -16, -18, 23, -4, -4,
+   48, 1, 7, 29, -14, -12, -16, 17,
+   35, 8, 0, -7, -2, 9, 8, 17,
+   -6, 53, -32, -21, -50, 5, 99, -60,
+   -5, -53, 10, -31, 12, -5, 7, 80,
+   36, 18, -31, 9, 98, 36, -63, -35,
+   4, -13, -28, -24, 28, -13, 18, 16,
+   -1, -18, -34, 10, 20, 7, 4, 29,
+   11, 25, -7, 36, 14, 45, 24, 1,
+   -16, 30, 6, 35, -6, -11, -24, 13,
+   -1, 27, 39, 20, 48, -11, -4, -13,
+   28, 11, -31, -18, 31, -29, 22, -2,
+   -20, -16, 5, 30, -12, -28, -3, 93,
+   -16, 23, 18, -29, 6, -54, -37, 28,
+   -3, -3, -47, -3, -36, -55, -3, 41,
+   -10, 47, -2, 23, 42, -7, -71, -27,
+   83, -64, 7, -24, 8, 26, -17, 15,
+   12, 31, -30, -38, -13, -33, -56, 4,
+   -17, 20, 18, 1, -30, -5, -6, -31,
+   -14, -37, 0, 22, 10, -30, 37, -17,
+   18, 6, 5, 23, -36, -32, 14, 18,
+   -13, -61, -52, -69, 44, -30, 16, 18,
+   -4, -25, 14, 81, 26, -8, -23, -59,
+   52, -104, 17, 119, -32, 26, 17, 1,
+   23, 45, 29, -64, -57, -14, 73, 21,
+   -13, -13, 9, -68, -7, -52, 3, 24,
+   -39, 44, -15, 27, 14, 19, -9, -28,
+   -11, 5, 3, -34, -2, 2, 22, -6,
+   -23, 4, 3, 13, -22, -13, -10, -18,
+   29, 6, 44, -13, -24, -8, 2, 30,
+   14, 43, 6, 17, -73, -6, -7, 20,
+   -80, -7, -7, -28, 15, -69, -38, -5,
+   -100, -35, 15, -79, 23, 29, -18, -27,
+   21, -66, -37, 8, -22, -39, 48, 4,
+   -13, 1, -9, 11, -29, 22, 6, -49,
+   32, -14, 47, -18, -4, 44, -52, -74,
+   43, 30, 23, -14, 5, 0, -27, 4,
+   -7, 10, -4, 10, 1, -16, 11, -18,
+   -2, -5, 2, -11, 0, -20, -4, 38,
+   74, 59, 39, 64, -10, 26, -3, -40,
+   -68, 3, -30, -51, 8, -19, -27, -46,
+   51, 52, 54, 36, 90, 92, 14, 13,
+   -5, 0, 16, -62, 16, 11, -47, -37,
+   -6, -5, 21, 54, -57, 32, 42, -6,
+   62, -9, 16, 21, 24, 9, -10, -4,
+   33, 50, 13, -15, 1, -35, -48, 18,
+   -11, -17, -67, -13, 21, 38, -44, 36,
+   -16, 29, 17, 5, -10, 18, 17, -32,
+   2, 8, 22, -56, -15, -32, 40, 43,
+   19, 46, -7, -100, -96, 19, 53, 24,
+   21, -26, -48, -101, -82, 61, 38, -85,
+   -28, -34, -1, 63, -5, -5, 39, 39,
+   -38, 32, -12, -28, 20, 40, -8, 2,
+   31, 12, -35, -13, 20, -25, 30, 8,
+   3, -13, -9, -20, 2, -13, 24, 37,
+   -10, 33, 6, 20, -16, -24, -6, -6,
+   -19, -5, 22, 21, 10, 11, -4, -39,
+   -1, 6, 49, 41, -15, -57, 21, -62,
+   77, -69, -13, 0, -74, 1, -7, -38,
+   -8, 6, 63, 28, 4, 26, -52, 82,
+   63, 13, 45, -33, 44, -52, -65, -21,
+   -46, -49, 64, -17, 32, 24, 68, -39,
+   -16, -5, -26, 28, 5, -61, -28, 2,
+   24, 11, -12, -33, 9, -37, -3, -28,
+   22, -37, -12, 19, 0, -18, -2, 14,
+   1, 4, 8, -9, -2, 43, -17, -2,
+   -66, -31, 56, -40, -87, -36, -2, -4,
+   -42, -45, -1, 31, -43, -15, 27, 63,
+   -11, 32, -10, -33, 27, -19, 4, 15,
+   -26, -34, 29, -4, -39, -65, 14, -20,
+   -21, -17, -36, 13, 59, 47, -38, -33,
+   13, -37, -8, -37, -7, -6, -76, -31,
+   -12, -46, 7, 24, -21, -30, -14, 9,
+   15, -12, -13, 47, -27, -25, -1, -39,
+   0, 20, -9, 6, 7, 4, 3, 7,
+   39, 50, 22, -7, 14, -20, 1, 70,
+   -28, 29, -41, 10, -16, -5, -28, -2,
+   -37, 32, -18, 17, 62, -11, -20, -50,
+   36, 21, -62, -12, -56, 52, 50, 17,
+   3, 48, 44, -41, -25, 3, 16, -3,
+   0, 33, -6, 15, 27, 34, -25, 22,
+   9, 17, -11, 36, 16, -2, 12, 21,
+   -52, 45, -2, -10, 46, 21, -18, 67,
+   -28, -13, 30, 37, 42, 16, -9, 11,
+   75, 7, -64, -40, -10, 29, 57, -23,
+   5, 53, -77, 3, -17, -5, 47, -55,
+   -35, -36, -13, 52, -53, -71, 52, -111,
+   -23, -26, -28, 29, -43, 55, -19, 43,
+   -19, 54, -12, -33, -44, -39, -19, -10,
+   -31, -10, 21, 38, -57, -20, 2, -25,
+   8, -6, 50, 12, 15, 25, -25, 15,
+   -30, -6, 9, 25, 37, 19, -4, 31,
+   -22, 2, 4, 2, 36, 7, 3, -34,
+   -80, 36, -10, -2, -5, 31, -36, 49,
+   -70, 20, -36, 21, 24, 25, -46, -51,
+   36, -58, -48, -40, -10, 55, 71, 47,
+   10, -1, 1, 2, -46, -68, 16, 13,
+   0, -74, -29, 73, -52, -18, -11, 7,
+   -44, -82, -32, -70, -28, -1, -39, -68,
+   -6, -41, 12, -22, -16, 40, -11, -25,
+   51, -9, 21, 4, 4, -34, 7, -78,
+   16, 6, -38, -30, -2, -44, 32, 0,
+   22, 64, 5, -72, -2, -14, -10, -16,
+   -8, -25, 12, 102, -58, 37, -10, -23,
+   15, 49, 7, -7, 2, -20, -32, 45,
+   -6, 48, 28, 30, 33, -1, 22, -6,
+   30, 65, -17, 29, 74, 37, -26, -10,
+   15, -24, 19, -66, 22, -10, -31, -1,
+   -18, -9, 11, 37, -4, 45, 5, 41,
+   17, 1, 1, 24, -58, 41, 5, -51,
+   14, 8, 43, 16, -10, -1, 45, 32,
+   -64, 3, -33, -25, -3, -27, -68, 12,
+   23, -11, -13, -37, -40, 4, -21, -12,
+   32, -23, -19, 76, 41, -23, -24, -44,
+   -65, -1, -15, 1, 71, 63, 5, 20,
+   -3, 21, -23, 31, -32, 18, -2, 27,
+   31, 46, -5, -39, -5, -35, 18, -18,
+   -40, -10, 3, 12, 2, -2, -22, 40,
+   5, -6, 60, 36, 3, 29, -27, 10,
+   25, -54, 5, 26, 39, 35, -24, -37,
+   30, -91, 28, -4, -21, -27, -39, -6,
+   5, 12, -128, 38, -16, 29, -95, -29,
+   82, -2, 35, 2, 12, 8, -22, 10,
+   80, -47, 2, -25, -73, -79, 16, -30,
+   -32, -66, 48, 21, -45, -11, -47, 14,
+   -27, -17, -7, 15, -44, -14, -44, -26,
+   -32, 26, -23, 17, -7, -28, 26, -6,
+   28, 6, -26, 2, 13, -14, -23, -14,
+   19, 46, 16, 2, -33, -21, 28, -17,
+   -42, 44, -37, 1, -39, 28, 84, -46,
+   15, 10, 13, -44, 72, -26, 26, 32,
+   -28, -12, -83, 2, 10, -30, -44, -10,
+   -28, 53, 45, 65, 0, -25, 57, 36,
+   -33, 6, 29, 44, -53, 11, 19, -2,
+   -27, 35, 32, 49, 4, 23, 38, 36,
+   24, 10, 51, -39, 4, -7, 26, 37,
+   -35, 11, -47, -18, 28, 16, -35, 42,
+   17, -21, -41, 28, 14, -12, 11, -45,
+   7, -43, -15, 18, -5, 38, -40, -50,
+   -30, -21, 9, -98, 13, 12, 23, 75,
+   -56, -7, -3, -4, -1, -34, 12, -49,
+   11, 26, -18, -28, -17, 33, 13, -14,
+   40, 24, -72, -37, 10, 17, -6, 22,
+   16, 16, -6, -12, -30, -14, 10, 40,
+   -23, 12, 15, -3, -15, 13, -56, -4,
+   -30, 1, -3, -17, 27, 50, -5, 64,
+   -36, -19, 7, 29, 22, 25, 9, -16,
+   -58, -69, -40, -61, -71, -14, 42, 93,
+   26, 11, -6, -58, -11, 70, -52, 19,
+   9, -30, -33, 11, -37, -47, -21, -22,
+   -40, 10, 47, 4, -23, 17, 48, 41,
+   -48, 14, 10, 15, 34, -23, -2, -47,
+   23, -32, -13, -10, -26, -26, -4, 16,
+   38, -14, 0, -12, -7, -7, 20, 44,
+   -1, -32, -27, -16, 4, -6, -18, 14,
+   5, 4, -29, 28, 7, -7, 15, -11,
+   -20, -45, -36, 16, 84, 34, -59, -30,
+   22, 126, 8, 68, 79, -17, 21, -68,
+   37, 5, 15, 63, 49, 127, -90, 85,
+   43, 7, 16, 9, 6, -45, -57, -43,
+   57, 11, -23, -11, -29, 60, -26, 0,
+   7, 42, -24, 10, 23, -25, 8, -7,
+   -40, 19, -17, 35, 4, 27, -39, -91,
+   27, -36, 34, 2, 16, -24, 25, 7,
+   -21, 5, 17, 10, -22, -30, 9, -17,
+   -61, -26, 33, 21, 58, -51, -14, 69,
+   -38, 20, 7, 80, -4, -65, -6, -27,
+   53, -12, 47, -1, -15, 1, 60, 102,
+   -79, -4, 12, 9, 22, 37, -8, -4,
+   37, 2, -3, -15, -16, -11, -5, 19,
+   -6, -43, 20, -25, -18, 10, -27, 0,
+   -28, -27, -11, 10, -18, -2, -4, -16,
+   26, 14, -6, 7, -6, 1, 53, -2,
+   -29, 23, 9, -30, -6, -4, -6, 56,
+   70, 0, -33, -20, -17, -9, -24, 46,
+   -5, -105, 47, -46, -51, 20, 20, -53,
+   -81, -1, -7, 75, -5, -21, -65, 12,
+   -52, 22, -50, -12, 49, 54, 76, -81,
+   10, 45, -41, -59, 18, -19, 25, 14,
+   -31, -53, -5, 12, 31, 84, -23, 2,
+   7, 2, 10, -32, 39, -2, -12, 1,
+   -9, 0, -10, -11, 9, 15, -8, -2,
+   2, -1, 10, 14, -5, -40, 19, -7,
+   -7, 26, -4, 2, 1, -27, 35, 32,
+   21, -31, 26, 43, -9, 4, -32, 40,
+   -62, -52, 36, 22, 38, 22, 36, -96,
+   6, -10, -23, -49, 15, -33, -18, -3,
+   0, 41, 21, -19, 21, 23, -39, -23,
+   -6, 6, 47, 56, 4, 74, 0, -98,
+   29, -47, -14, -36, 21, -22, 22, 16,
+   13, 12, 16, -5, 13, 17, -13, -15,
+   1, -34, -26, 26, 12, 32, 27, 13,
+   -67, 27, 2, 8, 10, 18, 16, 20,
+   -17, -17, 57, -64, 5, 14, 19, 31,
+   -18, -44, -46, -16, 4, -25, 17, -126,
+   -24, 39, 4, 8, 55, -25, -34, 39,
+   -16, 3, 9, 71, 72, -31, -55, 6,
+   10, -25, 32, -85, -21, 18, -8, 15,
+   12, -27, -7, 1, -21, -2, -5, 48,
+   -16, 18, 1, -22, -26, 16, 14, -31,
+   27, -6, -15, -21, 4, -14, 18, -36
+};
+
+static const opus_int8 layer1_recur_weights[1728] = {
+   20, 67, -99, 12, 41, -25, 49, -44,
+   35, 81, 110, 47, 34, -66, -14, 14,
+   -60, 34, 29, -73, 10, 41, 35, 89,
+   7, -35, 22, 7, 27, -20, -6, 56,
+   26, 66, 6, 33, -55, 53, 1, -21,
+   14, 17, 68, 55, 59, 0, 18, -9,
+   5, -41, 6, -5, -114, -12, 29, 42,
+   -23, 10, 81, -27, 20, -53, -30, -62,
+   40, 95, 25, -4, 3, 18, -8, -15,
+   -29, -82, 2, -57, -3, -61, -29, -29,
+   49, 2, -55, 5, -69, -99, -49, -51,
+   6, -25, 12, 89, 44, -33, 5, 41,
+   1, 23, -37, -37, -28, -48, 3, 4,
+   -41, -30, -57, -35, -39, -1, -13, -56,
+   -5, 50, 49, 41, -4, -4, 33, -22,
+   -1, 33, 34, 18, 40, -42, 12, 1,
+   -6, -2, 18, 17, 39, 44, 11, 65,
+   -60, -45, 10, 91, 21, 9, -62, -11,
+   8, 69, 37, 24, -30, 21, 26, -27,
+   1, -28, 24, 66, -8, 6, -71, 34,
+   24, 44, 58, -78, -19, 57, 17, -60,
+   1, 12, -3, -1, -40, 22, 11, -5,
+   25, 12, 1, 72, 79, 7, -50, 23,
+   18, 13, 21, -11, -20, 5, 77, -94,
+   24, 15, 57, -51, 3, 36, 53, -1,
+   4, 14, 30, -31, 22, 40, 32, -11,
+   -34, -36, -59, 58, 25, 21, -54, -23,
+   40, 46, 18, 0, 12, 54, -96, -99,
+   -59, 5, 119, -38, 50, 55, 12, -16,
+   67, 0, 34, 35, 39, 35, -1, 69,
+   24, 27, -30, -35, -4, -70, 2, -44,
+   -7, -6, 19, -9, 60, 44, -21, -10,
+   37, 43, -16, -3, 30, -15, -65, 31,
+   -55, 18, -98, 76, 64, 25, 24, -18,
+   -7, -68, -10, 38, 27, -60, 36, 33,
+   16, 30, 34, -39, -37, 31, 12, 53,
+   -54, 14, -26, -49, -128, -13, -5, -22,
+   -11, -85, 55, -8, -51, -11, -33, -10,
+   -31, -76, -41, 23, 44, -40, -54, -127,
+   -101, 19, -23, -15, 15, 27, 58, -60,
+   8, 14, -33, 1, 48, -9, -11, -123,
+   3, 53, 23, 4, -28, 22, 2, -29,
+   -67, 36, 12, 7, 55, -21, 88, 20,
+   -1, -21, -17, 3, 41, 32, -10, -14,
+   -5, -57, 67, 57, 21, 23, -2, -27,
+   -73, -24, 120, 21, 18, -35, 42, -7,
+   3, -45, -25, 76, -34, 50, 11, -54,
+   -91, 3, -113, -20, -5, 47, 15, -47,
+   17, 27, -3, -26, -7, 10, 7, 74,
+   -40, 64, -7, -5, -24, -49, -24, -3,
+   -10, 27, -17, -8, -3, 14, -27, 33,
+   13, 39, 28, -7, -38, 29, 16, 44,
+   19, 55, -3, 9, -13, -57, 43, 43,
+   31, 0, -93, -17, 19, -56, 4, -12,
+   -25, 37, -85, -13, -118, 33, -17, 56,
+   71, -80, -4, 6, -11, -18, 47, -52,
+   25, 9, 48, -107, 1, 21, 20, -3,
+   10, -16, -4, 24, 17, 31, -61, -18,
+   -50, 24, -10, 12, 71, 26, 11, -3,
+   4, 1, 0, -7, -40, 18, 38, -34,
+   38, 17, 8, -34, 2, 21, 123, -32,
+   -26, 43, 14, -34, -1, -9, 37, -16,
+   6, -17, -62, 68, 22, 17, 11, -75,
+   33, -80, 62, -9, -75, 76, 36, -41,
+   -8, -40, -11, -71, 40, -39, 62, -49,
+   -81, 16, -9, -52, 52, 61, 17, -103,
+   -27, -10, -8, -54, -57, 21, 23, -16,
+   -52, 36, 18, 10, -5, 8, 15, -29,
+   5, -19, -37, 8, -53, 6, 19, -37,
+   38, -17, 48, 10, 0, 81, 46, 70,
+   -29, 101, 11, 44, -44, -3, 24, 11,
+   3, 14, -9, 11, 14, -45, 13, 46,
+   -3, -57, 68, 44, 63, 98, 25, -28,
+   -23, 15, 32, -10, 53, -6, -2, -9,
+   -6, 16, -107, -11, -11, -28, 59, 57,
+   -22, 38, 42, 83, 27, 5, 29, -30,
+   12, -21, -13, 31, 38, -21, 58, -10,
+   -10, -15, -2, -5, 11, 12, -73, -28,
+   -38, 22, 2, -25, 73, -52, -12, -55,
+   32, -63, 21, 51, 33, 52, -26, 55,
+   -26, -26, 57, -32, -4, -52, -61, 21,
+   -33, -91, -51, 69, -90, -53, -38, -44,
+   12, -76, -20, 77, -45, -7, 86, 43,
+   -109, -33, -105, -40, -121, -10, 0, -72,
+   45, -51, -75, -49, -38, -1, -62, 18,
+   -1, 30, -44, -14, -10, -67, 40, -10,
+   -34, 46, -64, -32, 29, -13, 33, 3,
+   -32, -5, 28, -27, -25, 93, 24, 68,
+   -40, 57, 23, -3, -21, -58, 17, -39,
+   -17, -22, -89, 11, 18, -46, 27, 24,
+   46, 127, 61, 87, 31, 127, -36, 47,
+   -23, 47, 127, -24, 110, 122, 30, 100,
+   0, 96, -12, 6, 50, 44, -13, 73,
+   4, 55, -11, -15, 49, 42, -6, 20,
+   -35, 58, 18, 38, 42, 72, 19, -21,
+   11, 9, -37, 7, 29, 31, 16, -17,
+   13, -50, 19, 5, -23, 51, -16, -5,
+   4, -24, 76, 10, -53, -28, -7, -65,
+   74, 40, -16, -29, 32, -16, -49, -35,
+   -3, 59, -96, -50, -43, -43, -61, -15,
+   -8, -36, -34, -33, -14, 11, -3, -39,
+   4, -114, -123, -11, -49, -21, 14, -56,
+   1, 43, -63, 26, 40, 18, -10, -26,
+   -14, -15, -35, -35, -11, 32, -44, -67,
+   2, 22, 7, 3, -9, -30, -51, -28,
+   28, 6, -22, 16, 34, -25, -52, -54,
+   -8, -6, 5, 8, 20, -16, -17, -44,
+   27, 3, 31, -5, -48, -1, -3, 116,
+   11, 71, -31, -47, 109, 50, -22, -12,
+   -57, 32, 66, 8, -25, -93, -54, -10,
+   19, -76, -34, 97, 48, -36, -18, -30,
+   -39, -26, -12, 28, 14, 12, -12, -31,
+   38, 2, 10, 4, -40, 20, 16, -61,
+   2, 64, 39, 5, 15, 33, 40, -61,
+   -49, 93, -10, 33, 28, -11, -27, -18,
+   39, -62, -6, -6, 62, 11, -8, 38,
+   -67, 12, 27, 39, -27, 123, -18, -6,
+   -65, 83, -64, 20, 19, -11, 33, 24,
+   17, 56, 78, 7, -15, 54, -101, -9,
+   115, -96, 50, 51, 35, 34, 27, 37,
+   -40, -11, 8, -36, 42, -45, 2, -23,
+   0, 67, -8, -9, -13, 50, -14, -27,
+   4, 0, -8, -14, 30, -9, 29, 15,
+   9, -38, 37, -8, 50, -46, 54, 41,
+   -11, -8, -11, -26, 39, 45, 14, -26,
+   -17, -27, 69, 38, 39, 98, 66, 0,
+   42, 123, -101, -19, -83, 117, -32, 56,
+   10, 12, -88, 79, -53, 56, 63, 95,
+   -62, 9, 36, -13, -79, -16, 37, -46,
+   35, -34, 14, 17, -54, 5, 21, -7,
+   7, 63, 56, 15, 27, -76, -25, 4,
+   -26, -63, 28, -67, -52, 43, -47, -70,
+   40, -12, 40, -66, -37, 0, 35, 37,
+   -53, 4, -17, -51, 11, 21, 14, -34,
+   -4, 24, -42, 29, 22, 7, 28, 12,
+   37, 39, -39, -19, 65, -60, -50, -2,
+   1, 82, 39, 19, -23, -43, -22, -67,
+   -35, -34, 32, 102, 81, 127, 36, 67,
+   -45, 1, -67, -52, -4, 35, 20, 28,
+   71, 86, -35, -9, -83, -34, 12, 9,
+   -23, 2, 14, 28, -23, 7, -25, 45,
+   7, 17, -37, 0, -19, 31, 26, 40,
+   -27, -16, 17, 5, -21, 23, 24, 96,
+   -55, 52, -19, -14, -6, 1, 50, -34,
+   86, -53, 38, 2, -52, -36, -13, 60,
+   -85, -120, 32, 7, -12, 22, 70, -7,
+   -94, 38, -76, -31, -20, 15, -28, 7,
+   6, 40, 53, 88, 3, 38, 18, -8,
+   -22, -23, 51, 37, -9, 13, -32, 25,
+   -21, 27, 31, 20, 18, -9, -13, 1,
+   21, -24, -13, 39, 15, -11, -29, -36,
+   18, 15, 8, 27, 21, -94, -1, -22,
+   49, 66, -1, 6, -3, -40, -18, 6,
+   28, 12, 33, -59, 62, 60, -48, 90,
+   -1, 108, 9, 18, -2, 27, 77, -65,
+   82, -48, -38, -19, -11, 127, 50, 66,
+   18, -13, -22, 60, -38, 40, -14, -26,
+   -13, 38, 67, 57, 30, 33, 26, 36,
+   38, -17, 27, -28, 20, 12, -64, 18,
+   5, -33, -27, 13, -26, 32, 35, -5,
+   -48, -14, 92, 43, -47, -14, 40, 11,
+   51, 66, 22, -63, -16, -61, 4, -28,
+   27, 20, -33, -30, -21, -29, -53, 31,
+   -40, 24, 43, -4, -19, 21, 67, 20,
+   100, -16, -93, 78, -6, -18, -52, -37,
+   -9, 66, -31, -8, 26, 18, 4, 24,
+   -22, 17, -2, -13, 27, 0, 8, -18,
+   -25, 5, -21, -24, -7, 18, -93, 21,
+   7, 2, -75, 69, 50, -5, -15, -17,
+   60, -42, 55, 1, -4, 3, 10, 46,
+   16, -13, 45, -7, -10, -44, -108, 49,
+   2, -15, -64, -12, -72, 32, -38, -45,
+   10, -54, 13, -13, -27, -36, -64, 58,
+   -62, -101, 88, -86, -71, -39, -9, -128,
+   32, 15, -4, 54, -16, -39, -26, -36,
+   46, 48, -64, -10, 19, 30, -13, 34,
+   -8, 50, 60, -22, -6, -11, -30, 5,
+   50, 32, 56, 0, 25, 6, 68, 11,
+   -29, 45, -9, -12, 4, 1, 18, -49,
+   0, -38, -19, 90, 29, 35, 51, 8,
+   -48, 96, -1, -12, -9, -32, -63, -65,
+   -7, 38, 89, 28, -85, -28, -23, -25,
+   -128, 56, 79, -36, 99, -6, -37, 7,
+   -13, -69, -46, -29, 25, 64, -21, 17,
+   1, 42, -66, 1, 80, 26, -32, 21,
+   15, 15, 6, 6, -10, 15, 127, 5,
+   38, 27, 87, -57, -25, 11, 72, -21,
+   -5, 11, -13, -66, 78, 36, -3, 41,
+   -21, 8, -33, 23, 73, 28, 57, -25,
+   -5, 4, -22, -47, 15, 4, -57, -72,
+   33, 1, 18, 2, 53, -71, -99, -21,
+   -3, -111, 108, 71, -14, 82, 25, 61,
+   -48, 5, 9, -51, -20, -25, -3, 14,
+   -33, 14, -3, -34, 22, 12, -19, -38,
+   -16, 2, 21, 16, 26, -31, 75, 44,
+   -31, 16, 26, 66, 17, -9, -22, -22,
+   22, -44, 22, 27, 2, 58, -14, 10,
+   -73, -42, 55, -25, -61, 72, -1, 30,
+   -58, -25, 63, 26, -48, -40, 26, -30,
+   60, 8, -17, -1, -18, -20, 43, -20,
+   -4, -28, 127, -106, 29, 70, 64, -27,
+   39, -33, -5, -88, -40, -52, 26, 44,
+   -17, 23, 2, -49, 22, -9, -8, 86,
+   49, -43, -60, 1, 10, 45, 36, -53,
+   -4, 33, 38, 48, -72, 1, 19, 21,
+   -65, 4, -5, -62, 27, -25, 17, -6,
+   6, -45, -39, -46, 4, 26, 127, -9,
+   18, -33, -18, -3, 33, 2, -5, 15,
+   -26, -22, -117, -63, -17, -59, 61, -74,
+   7, -47, -58, -128, -67, 15, -16, -128,
+   12, 2, 20, 9, -48, -40, 43, 3,
+   -40, -16, -38, -6, -22, -28, -16, -59,
+   -22, 6, -5, 11, -12, -66, -40, 27,
+   -62, -44, -19, 38, -3, 39, -8, 40,
+   -24, 13, 21, 50, -60, -22, 53, -29,
+   -6, 1, 22, -59, 0, 17, -39, 115
+};
+
+static const opus_int8 layer1_bias[72] = {
+   -42, 20, 16, 0, 105, 60, 1, -97,
+   24, 60, 18, 13, 62, 25, 127, 34,
+   79, 55, 118, 127, 95, 31, -4, 87,
+   21, 12, 2, -14, 18, 23, 8, 17,
+   -1, -8, 5, 4, 24, 37, 21, 13,
+   36, 13, 17, 18, 37, 30, 33, 1,
+   8, -16, -11, -5, -31, -3, -5, 0,
+   6, 3, 58, -7, -1, -16, 5, -13,
+   16, 10, -2, -14, 11, -4, 3, -11
+};
+
+static const opus_int8 layer2_weights[48] = {
+   -113, -88, 31, -128, -126, -61, 85, -35,
+   118, -128, -61, 127, -128, -17, -128, 127,
+   104, -9, -128, 33, 45, 127, 5, 83,
+   84, -128, -85, -128, -45, 48, -53, -128,
+   46, 127, -17, 125, 117, -41, -117, -91,
+   -127, -68, -1, -89, -80, 32, 106, 7
+};
+
+static const opus_int8 layer2_bias[2] = {
+   14, 117
+};
+
+const DenseLayer layer0 = {
+   layer0_bias,
+   layer0_weights,
+   25, 32, 0
+};
+
+const GRULayer layer1 = {
+   layer1_bias,
+   layer1_weights,
+   layer1_recur_weights,
+   32, 24
+};
+
+const DenseLayer layer2 = {
+   layer2_bias,
+   layer2_weights,
+   24, 2, 1
+};
+
diff --git a/src/mlp_train.c b/src/mlp_train.c
deleted file mode 100644
index 8d9d127..0000000
--- a/src/mlp_train.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/* Copyright (c) 2008-2011 Octasic Inc.
-   Written by Jean-Marc Valin */
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
-   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-#include "mlp_train.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <semaphore.h>
-#include <pthread.h>
-#include <time.h>
-#include <signal.h>
-
-int stopped = 0;
-
-void handler(int sig)
-{
-    stopped = 1;
-    signal(sig, handler);
-}
-
-MLPTrain * mlp_init(int *topo, int nbLayers, float *inputs, float *outputs, int nbSamples)
-{
-    int i, j, k;
-    MLPTrain *net;
-    int inDim, outDim;
-    net = malloc(sizeof(*net));
-    net->topo = malloc(nbLayers*sizeof(net->topo[0]));
-    for (i=0;i<nbLayers;i++)
-        net->topo[i] = topo[i];
-    inDim = topo[0];
-    outDim = topo[nbLayers-1];
-    net->in_rate = malloc((inDim+1)*sizeof(net->in_rate[0]));
-    net->weights = malloc((nbLayers-1)*sizeof(net->weights));
-    net->best_weights = malloc((nbLayers-1)*sizeof(net->weights));
-    for (i=0;i<nbLayers-1;i++)
-    {
-        net->weights[i] = malloc((topo[i]+1)*topo[i+1]*sizeof(net->weights[0][0]));
-        net->best_weights[i] = malloc((topo[i]+1)*topo[i+1]*sizeof(net->weights[0][0]));
-    }
-    double inMean[inDim];
-    for (j=0;j<inDim;j++)
-    {
-        double std=0;
-        inMean[j] = 0;
-        for (i=0;i<nbSamples;i++)
-        {
-            inMean[j] += inputs[i*inDim+j];
-            std += inputs[i*inDim+j]*inputs[i*inDim+j];
-        }
-        inMean[j] /= nbSamples;
-        std /= nbSamples;
-        net->in_rate[1+j] = .5/(.0001+std);
-        std = std-inMean[j]*inMean[j];
-        if (std<.001)
-            std = .001;
-        std = 1/sqrt(inDim*std);
-        for (k=0;k<topo[1];k++)
-            net->weights[0][k*(topo[0]+1)+j+1] = randn(std);
-    }
-    net->in_rate[0] = 1;
-    for (j=0;j<topo[1];j++)
-    {
-        double sum = 0;
-        for (k=0;k<inDim;k++)
-            sum += inMean[k]*net->weights[0][j*(topo[0]+1)+k+1];
-        net->weights[0][j*(topo[0]+1)] = -sum;
-    }
-    for (j=0;j<outDim;j++)
-    {
-        double mean = 0;
-        double std;
-        for (i=0;i<nbSamples;i++)
-            mean += outputs[i*outDim+j];
-        mean /= nbSamples;
-        std = 1/sqrt(topo[nbLayers-2]);
-        net->weights[nbLayers-2][j*(topo[nbLayers-2]+1)] = mean;
-        for (k=0;k<topo[nbLayers-2];k++)
-            net->weights[nbLayers-2][j*(topo[nbLayers-2]+1)+k+1] = randn(std);
-    }
-    return net;
-}
-
-#define MAX_NEURONS 100
-#define MAX_OUT 10
-
-double compute_gradient(MLPTrain *net, float *inputs, float *outputs, int nbSamples, double *W0_grad, double *W1_grad, double *error_rate)
-{
-    int i,j;
-    int s;
-    int inDim, outDim, hiddenDim;
-    int *topo;
-    double *W0, *W1;
-    double rms=0;
-    int W0_size, W1_size;
-    double hidden[MAX_NEURONS];
-    double netOut[MAX_NEURONS];
-    double error[MAX_NEURONS];
-
-    topo = net->topo;
-    inDim = net->topo[0];
-    hiddenDim = net->topo[1];
-    outDim = net->topo[2];
-    W0_size = (topo[0]+1)*topo[1];
-    W1_size = (topo[1]+1)*topo[2];
-    W0 = net->weights[0];
-    W1 = net->weights[1];
-    memset(W0_grad, 0, W0_size*sizeof(double));
-    memset(W1_grad, 0, W1_size*sizeof(double));
-    for (i=0;i<outDim;i++)
-        netOut[i] = outputs[i];
-    for (i=0;i<outDim;i++)
-        error_rate[i] = 0;
-    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]*inp[j];
-            hidden[i] = tansig_approx(sum);
-        }
-        for (i=0;i<outDim;i++)
-        {
-            double sum = W1[i*(hiddenDim+1)];
-            for (j=0;j<hiddenDim;j++)
-                sum += W1[i*(hiddenDim+1)+j+1]*hidden[j];
-            netOut[i] = tansig_approx(sum);
-            error[i] = out[i] - netOut[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++)
-        {
-            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];
-        }
-        for (i=0;i<hiddenDim;i++)
-        {
-            double grad;
-            grad = 0;
-            for (j=0;j<outDim;j++)
-                grad += error[j]*W1[j*(hiddenDim+1)+i+1];
-            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*inp[j];
-        }
-    }
-    return rms;
-}
-
-#define NB_THREADS 8
-
-sem_t sem_begin[NB_THREADS];
-sem_t sem_end[NB_THREADS];
-
-struct GradientArg {
-    int id;
-    int done;
-    MLPTrain *net;
-    float *inputs;
-    float *outputs;
-    int nbSamples;
-    double *W0_grad;
-    double *W1_grad;
-    double rms;
-    double error_rate[MAX_OUT];
-};
-
-void *gradient_thread_process(void *_arg)
-{
-    int W0_size, W1_size;
-    struct GradientArg *arg = _arg;
-    int *topo = arg->net->topo;
-    W0_size = (topo[0]+1)*topo[1];
-    W1_size = (topo[1]+1)*topo[2];
-    double W0_grad[W0_size];
-    double W1_grad[W1_size];
-    arg->W0_grad = W0_grad;
-    arg->W1_grad = W1_grad;
-    while (1)
-    {
-        sem_wait(&sem_begin[arg->id]);
-        if (arg->done)
-            break;
-        arg->rms = compute_gradient(arg->net, arg->inputs, arg->outputs, arg->nbSamples, arg->W0_grad, arg->W1_grad, arg->error_rate);
-        sem_post(&sem_end[arg->id]);
-    }
-    fprintf(stderr, "done\n");
-    return NULL;
-}
-
-float mlp_train_backprop(MLPTrain *net, float *inputs, float *outputs, int nbSamples, int nbEpoch, float rate)
-{
-    int i, j;
-    int e;
-    float best_rms = 1e10;
-    int inDim, outDim, hiddenDim;
-    int *topo;
-    double *W0, *W1, *best_W0, *best_W1;
-    double *W0_grad, *W1_grad;
-    double *W0_oldgrad, *W1_oldgrad;
-    double *W0_rate, *W1_rate;
-    double *best_W0_rate, *best_W1_rate;
-    int W0_size, W1_size;
-    topo = net->topo;
-    W0_size = (topo[0]+1)*topo[1];
-    W1_size = (topo[1]+1)*topo[2];
-    struct GradientArg args[NB_THREADS];
-    pthread_t thread[NB_THREADS];
-    int samplePerPart = nbSamples/NB_THREADS;
-    int count_worse=0;
-    int count_retries=0;
-
-    topo = net->topo;
-    inDim = net->topo[0];
-    hiddenDim = net->topo[1];
-    outDim = net->topo[2];
-    W0 = net->weights[0];
-    W1 = net->weights[1];
-    best_W0 = net->best_weights[0];
-    best_W1 = net->best_weights[1];
-    W0_grad = malloc(W0_size*sizeof(double));
-    W1_grad = malloc(W1_size*sizeof(double));
-    W0_oldgrad = malloc(W0_size*sizeof(double));
-    W1_oldgrad = malloc(W1_size*sizeof(double));
-    W0_rate = malloc(W0_size*sizeof(double));
-    W1_rate = malloc(W1_size*sizeof(double));
-    best_W0_rate = malloc(W0_size*sizeof(double));
-    best_W1_rate = malloc(W1_size*sizeof(double));
-    memset(W0_grad, 0, W0_size*sizeof(double));
-    memset(W0_oldgrad, 0, W0_size*sizeof(double));
-    memset(W1_grad, 0, W1_size*sizeof(double));
-    memset(W1_oldgrad, 0, W1_size*sizeof(double));
-
-    rate /= nbSamples;
-    for (i=0;i<hiddenDim;i++)
-        for (j=0;j<inDim+1;j++)
-            W0_rate[i*(inDim+1)+j] = rate*net->in_rate[j];
-    for (i=0;i<W1_size;i++)
-        W1_rate[i] = rate;
-
-    for (i=0;i<NB_THREADS;i++)
-    {
-        args[i].net = net;
-        args[i].inputs = inputs+i*samplePerPart*inDim;
-        args[i].outputs = outputs+i*samplePerPart*outDim;
-        args[i].nbSamples = samplePerPart;
-        args[i].id = i;
-        args[i].done = 0;
-        sem_init(&sem_begin[i], 0, 0);
-        sem_init(&sem_end[i], 0, 0);
-        pthread_create(&thread[i], NULL, gradient_thread_process, &args[i]);
-    }
-    for (e=0;e<nbEpoch;e++)
-    {
-        double rms=0;
-        double error_rate[2] = {0,0};
-        for (i=0;i<NB_THREADS;i++)
-        {
-            sem_post(&sem_begin[i]);
-        }
-        memset(W0_grad, 0, W0_size*sizeof(double));
-        memset(W1_grad, 0, W1_size*sizeof(double));
-        for (i=0;i<NB_THREADS;i++)
-        {
-            sem_wait(&sem_end[i]);
-            rms += args[i].rms;
-            error_rate[0] += args[i].error_rate[0];
-            error_rate[1] += args[i].error_rate[1];
-            for (j=0;j<W0_size;j++)
-                W0_grad[j] += args[i].W0_grad[j];
-            for (j=0;j<W1_size;j++)
-                W1_grad[j] += args[i].W1_grad[j];
-        }
-
-        float mean_rate = 0, min_rate = 1e10;
-        rms = (rms/(outDim*nbSamples));
-        error_rate[0] = (error_rate[0]/(nbSamples));
-        error_rate[1] = (error_rate[1]/(nbSamples));
-        fprintf (stderr, "%f %f (%f %f) ", error_rate[0], error_rate[1], rms, best_rms);
-        if (rms < best_rms)
-        {
-            best_rms = rms;
-            for (i=0;i<W0_size;i++)
-            {
-                best_W0[i] = W0[i];
-                best_W0_rate[i] = W0_rate[i];
-            }
-            for (i=0;i<W1_size;i++)
-            {
-                best_W1[i] = W1[i];
-                best_W1_rate[i] = W1_rate[i];
-            }
-            count_worse=0;
-            count_retries=0;
-        } else {
-            count_worse++;
-            if (count_worse>30)
-            {
-                count_retries++;
-                count_worse=0;
-                for (i=0;i<W0_size;i++)
-                {
-                    W0[i] = best_W0[i];
-                    best_W0_rate[i] *= .7;
-                    if (best_W0_rate[i]<1e-15) best_W0_rate[i]=1e-15;
-                    W0_rate[i] = best_W0_rate[i];
-                    W0_grad[i] = 0;
-                }
-                for (i=0;i<W1_size;i++)
-                {
-                    W1[i] = best_W1[i];
-                    best_W1_rate[i] *= .8;
-                    if (best_W1_rate[i]<1e-15) best_W1_rate[i]=1e-15;
-                    W1_rate[i] = best_W1_rate[i];
-                    W1_grad[i] = 0;
-                }
-            }
-        }
-        if (count_retries>10)
-            break;
-        for (i=0;i<W0_size;i++)
-        {
-            if (W0_oldgrad[i]*W0_grad[i] > 0)
-                W0_rate[i] *= 1.01;
-            else if (W0_oldgrad[i]*W0_grad[i] < 0)
-                W0_rate[i] *= .9;
-            mean_rate += W0_rate[i];
-            if (W0_rate[i] < min_rate)
-                min_rate = W0_rate[i];
-            if (W0_rate[i] < 1e-15)
-                W0_rate[i] = 1e-15;
-            /*if (W0_rate[i] > .01)
-                W0_rate[i] = .01;*/
-            W0_oldgrad[i] = W0_grad[i];
-            W0[i] += W0_grad[i]*W0_rate[i];
-        }
-        for (i=0;i<W1_size;i++)
-        {
-            if (W1_oldgrad[i]*W1_grad[i] > 0)
-                W1_rate[i] *= 1.01;
-            else if (W1_oldgrad[i]*W1_grad[i] < 0)
-                W1_rate[i] *= .9;
-            mean_rate += W1_rate[i];
-            if (W1_rate[i] < min_rate)
-                min_rate = W1_rate[i];
-            if (W1_rate[i] < 1e-15)
-                W1_rate[i] = 1e-15;
-            W1_oldgrad[i] = W1_grad[i];
-            W1[i] += W1_grad[i]*W1_rate[i];
-        }
-        mean_rate /= (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2];
-        fprintf (stderr, "%g %d", mean_rate, e);
-        if (count_retries)
-            fprintf(stderr, " %d", count_retries);
-        fprintf(stderr, "\n");
-        if (stopped)
-            break;
-    }
-    for (i=0;i<NB_THREADS;i++)
-    {
-        args[i].done = 1;
-        sem_post(&sem_begin[i]);
-        pthread_join(thread[i], NULL);
-        fprintf (stderr, "joined %d\n", i);
-    }
-    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;
-}
-
-int main(int argc, char **argv)
-{
-    int i, j;
-    int nbInputs;
-    int nbOutputs;
-    int nbHidden;
-    int nbSamples;
-    int nbEpoch;
-    int nbRealInputs;
-    unsigned int seed;
-    int ret;
-    float rms;
-    float *inputs;
-    float *outputs;
-    if (argc!=6)
-    {
-        fprintf (stderr, "usage: mlp_train <inputs> <hidden> <outputs> <nb samples> <nb epoch>\n");
-        return 1;
-    }
-    nbInputs = atoi(argv[1]);
-    nbHidden = atoi(argv[2]);
-    nbOutputs = atoi(argv[3]);
-    nbSamples = atoi(argv[4]);
-    nbEpoch = atoi(argv[5]);
-    nbRealInputs = nbInputs;
-    inputs = malloc(nbInputs*nbSamples*sizeof(*inputs));
-    outputs = malloc(nbOutputs*nbSamples*sizeof(*outputs));
-
-    seed = time(NULL);
-    /*seed = 1452209040;*/
-    fprintf (stderr, "Seed is %u\n", seed);
-    srand(seed);
-    build_tansig_table();
-    signal(SIGTERM, handler);
-    signal(SIGINT, handler);
-    signal(SIGHUP, handler);
-    for (i=0;i<nbSamples;i++)
-    {
-        for (j=0;j<nbRealInputs;j++)
-            ret = scanf(" %f", &inputs[i*nbInputs+j]);
-        for (j=0;j<nbOutputs;j++)
-            ret = scanf(" %f", &outputs[i*nbOutputs+j]);
-        if (feof(stdin))
-        {
-            nbSamples = i;
-            break;
-        }
-    }
-    int topo[3] = {nbInputs, nbHidden, nbOutputs};
-    MLPTrain *net;
-
-    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]);
-        if (i%5==4)
-            printf("\n");
-        else
-            printf(" ");
-    }
-    printf ("\n/* output layer */\n");
-    for (i=0;i<(topo[1]+1)*topo[2];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 ("    3,\n");
-    printf ("    topo,\n");
-    printf ("    weights\n};\n");
-    return 0;
-}
diff --git a/src/mlp_train.h b/src/mlp_train.h
deleted file mode 100644
index 4940415..0000000
--- a/src/mlp_train.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Copyright (c) 2008-2011 Octasic Inc.
-   Written by Jean-Marc Valin */
-/*
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:
-
-   - Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-   - Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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 _MLP_TRAIN_H_
-#define _MLP_TRAIN_H_
-
-#include <math.h>
-#include <stdlib.h>
-
-double tansig_table[501];
-static inline double tansig_double(double x)
-{
-    return 2./(1.+exp(-2.*x)) - 1.;
-}
-static inline void build_tansig_table(void)
-{
-    int i;
-    for (i=0;i<501;i++)
-        tansig_table[i] = tansig_double(.04*(i-250));
-}
-
-static inline double tansig_approx(double x)
-{
-    int i;
-    double y, dy;
-    if (x>=10)
-        return 1;
-    if (x<=-10)
-        return -1;
-    i = lrint(25*x);
-    x -= .04*i;
-    y = tansig_table[250+i];
-    dy = 1-y*y;
-    y = y + x*dy*(1 - y*x);
-    return y;
-}
-
-static inline float randn(float sd)
-{
-   float U1, U2, S, x;
-   do {
-      U1 = ((float)rand())/RAND_MAX;
-      U2 = ((float)rand())/RAND_MAX;
-      U1 = 2*U1-1;
-      U2 = 2*U2-1;
-      S = U1*U1 + U2*U2;
-   } while (S >= 1 || S == 0.0f);
-   x = sd*sqrt(-2 * log(S) / S) * U1;
-   return x;
-}
-
-
-typedef struct {
-    int layers;
-    int *topo;
-    double **weights;
-    double **best_weights;
-    double *in_rate;
-} MLPTrain;
-
-
-#endif /* _MLP_TRAIN_H_ */
diff --git a/src/opus.c b/src/opus.c
index cdbd13a..538b5ea 100644
--- a/src/opus.c
+++ b/src/opus.c
@@ -252,7 +252,7 @@
       /* Number of frames encoded in bits 0 to 5 */
       ch = *data++;
       count = ch&0x3F;
-      if (count <= 0 || framesize*count > 5760)
+      if (count <= 0 || framesize*(opus_int32)count > 5760)
          return OPUS_INVALID_PACKET;
       len--;
       /* Padding flag is bit 6 */
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 149ae7f..9113638 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -78,6 +78,26 @@
    opus_uint32  rangeFinal;
 };
 
+#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
+static void validate_opus_decoder(OpusDecoder *st)
+{
+   celt_assert(st->channels == 1 || st->channels == 2);
+   celt_assert(st->Fs == 48000 || st->Fs == 24000 || st->Fs == 16000 || st->Fs == 12000 || st->Fs == 8000);
+   celt_assert(st->DecControl.API_sampleRate == st->Fs);
+   celt_assert(st->DecControl.internalSampleRate == 0 || st->DecControl.internalSampleRate == 16000 || st->DecControl.internalSampleRate == 12000 || st->DecControl.internalSampleRate == 8000);
+   celt_assert(st->DecControl.nChannelsAPI == st->channels);
+   celt_assert(st->DecControl.nChannelsInternal == 0 || st->DecControl.nChannelsInternal == 1 || st->DecControl.nChannelsInternal == 2);
+   celt_assert(st->DecControl.payloadSize_ms == 0 || st->DecControl.payloadSize_ms == 10 || st->DecControl.payloadSize_ms == 20 || st->DecControl.payloadSize_ms == 40 || st->DecControl.payloadSize_ms == 60);
+#ifdef OPUS_ARCHMASK
+   celt_assert(st->arch >= 0);
+   celt_assert(st->arch <= OPUS_ARCHMASK);
+#endif
+   celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
+}
+#define VALIDATE_OPUS_DECODER(st) validate_opus_decoder(st)
+#else
+#define VALIDATE_OPUS_DECODER(st)
+#endif
 
 int opus_decoder_get_size(int channels)
 {
@@ -104,7 +124,7 @@
       return OPUS_BAD_ARG;
 
    OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
-   /* Initialize SILK encoder */
+   /* Initialize SILK decoder */
    ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
    if (ret)
       return OPUS_INTERNAL_ERROR;
@@ -217,6 +237,7 @@
 
    int audiosize;
    int mode;
+   int bandwidth;
    int transition=0;
    int start_band;
    int redundancy=0;
@@ -253,10 +274,12 @@
    {
       audiosize = st->frame_size;
       mode = st->mode;
+      bandwidth = st->bandwidth;
       ec_dec_init(&dec,(unsigned char*)data,len);
    } else {
       audiosize = frame_size;
       mode = st->prev_mode;
+      bandwidth = 0;
 
       if (mode == 0)
       {
@@ -355,15 +378,15 @@
       {
         st->DecControl.nChannelsInternal = st->stream_channels;
         if( mode == MODE_SILK_ONLY ) {
-           if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
+           if( bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
               st->DecControl.internalSampleRate = 8000;
-           } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
+           } else if( bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
               st->DecControl.internalSampleRate = 12000;
-           } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
+           } else if( bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
               st->DecControl.internalSampleRate = 16000;
            } else {
               st->DecControl.internalSampleRate = 16000;
-              silk_assert( 0 );
+              celt_assert( 0 );
            }
         } else {
            /* Hybrid mode */
@@ -427,29 +450,6 @@
    if (mode != MODE_CELT_ONLY)
       start_band = 17;
 
-   {
-      int endband=21;
-
-      switch(st->bandwidth)
-      {
-      case OPUS_BANDWIDTH_NARROWBAND:
-         endband = 13;
-         break;
-      case OPUS_BANDWIDTH_MEDIUMBAND:
-      case OPUS_BANDWIDTH_WIDEBAND:
-         endband = 17;
-         break;
-      case OPUS_BANDWIDTH_SUPERWIDEBAND:
-         endband = 19;
-         break;
-      case OPUS_BANDWIDTH_FULLBAND:
-         endband = 21;
-         break;
-      }
-      celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));
-      celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
-   }
-
    if (redundancy)
    {
       transition = 0;
@@ -464,6 +464,34 @@
       opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
    }
 
+
+   if (bandwidth)
+   {
+      int endband=21;
+
+      switch(bandwidth)
+      {
+      case OPUS_BANDWIDTH_NARROWBAND:
+         endband = 13;
+         break;
+      case OPUS_BANDWIDTH_MEDIUMBAND:
+      case OPUS_BANDWIDTH_WIDEBAND:
+         endband = 17;
+         break;
+      case OPUS_BANDWIDTH_SUPERWIDEBAND:
+         endband = 19;
+         break;
+      case OPUS_BANDWIDTH_FULLBAND:
+         endband = 21;
+         break;
+      default:
+         celt_assert(0);
+         break;
+      }
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)));
+   }
+   MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)));
+
    /* Only allocation memory for redundancy if/when needed */
    redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
    ALLOC(redundant_audio, redundant_audio_size, opus_val16);
@@ -471,21 +499,21 @@
    /* 5 ms redundant frame for CELT->SILK*/
    if (redundancy && celt_to_silk)
    {
-      celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
       celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
                           redundant_audio, F5, NULL, 0);
-      celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
    }
 
    /* MUST be after PLC */
-   celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
+   MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)));
 
    if (mode != MODE_SILK_ONLY)
    {
       int celt_frame_size = IMIN(F20, frame_size);
       /* Make sure to discard any previous CELT state */
       if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
-         celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
+         MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
       /* Decode CELT */
       celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
                                      len, pcm, celt_frame_size, &dec, celt_accum);
@@ -500,7 +528,7 @@
          do a fade-out by decoding a silence frame */
       if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
       {
-         celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+         MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
          celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
       }
    }
@@ -518,18 +546,18 @@
 
    {
       const CELTMode *celt_mode;
-      celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)));
       window = celt_mode->window;
    }
 
    /* 5 ms redundant frame for SILK->CELT */
    if (redundancy && !celt_to_silk)
    {
-      celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
-      celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
 
       celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
-      celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
+      MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
       smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
                   pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
    }
@@ -605,6 +633,7 @@
    int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
    /* 48 x 2.5 ms = 120 ms */
    opus_int16 size[48];
+   VALIDATE_OPUS_DECODER(st);
    if (decode_fec<0 || decode_fec>1)
       return OPUS_BAD_ARG;
    /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
@@ -740,6 +769,7 @@
       else
          return OPUS_INVALID_PACKET;
    }
+   celt_assert(st->channels == 1 || st->channels == 2);
    ALLOC(out, frame_size*st->channels, opus_int16);
 
    ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);
@@ -777,6 +807,7 @@
       else
          return OPUS_INVALID_PACKET;
    }
+   celt_assert(st->channels == 1 || st->channels == 2);
    ALLOC(out, frame_size*st->channels, float);
 
    ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);
@@ -864,7 +895,7 @@
          goto bad_arg;
       }
       if (st->prev_mode == MODE_CELT_ONLY)
-         celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
+         ret = celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
       else
          *value = st->DecControl.prevPitchLag;
    }
@@ -906,7 +937,7 @@
        {
           goto bad_arg;
        }
-       celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
+       ret = celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
    }
    break;
    case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
@@ -916,7 +947,7 @@
        {
           goto bad_arg;
        }
-       celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
+       ret = celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
    }
    break;
    default:
diff --git a/src/opus_demo.c b/src/opus_demo.c
index 50987c9..4cc26a6 100644
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -79,14 +79,7 @@
          | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
 }
 
-static void check_encoder_option(int decode_only, const char *opt)
-{
-   if (decode_only)
-   {
-      fprintf(stderr, "option %s is only for encoding\n", opt);
-      exit(EXIT_FAILURE);
-   }
-}
+#define check_encoder_option(decode_only, opt) do {if (decode_only) {fprintf(stderr, "option %s is only for encoding\n", opt); goto failure;}} while(0)
 
 static const int silk8_test[][4] = {
       {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
@@ -218,15 +211,16 @@
 {
     int err;
     char *inFile, *outFile;
-    FILE *fin, *fout;
+    FILE *fin=NULL;
+    FILE *fout=NULL;
     OpusEncoder *enc=NULL;
     OpusDecoder *dec=NULL;
     int args;
     int len[2];
     int frame_size, channels;
     opus_int32 bitrate_bps=0;
-    unsigned char *data[2];
-    unsigned char *fbytes;
+    unsigned char *data[2] = {NULL, NULL};
+    unsigned char *fbytes=NULL;
     opus_int32 sampling_rate;
     int use_vbr;
     int max_payload_bytes;
@@ -240,7 +234,8 @@
     int k;
     opus_int32 skip=0;
     int stop=0;
-    short *in, *out;
+    short *in=NULL;
+    short *out=NULL;
     int application=OPUS_APPLICATION_AUDIO;
     double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
     double tot_samples=0;
@@ -268,11 +263,12 @@
     int remaining=0;
     int variable_duration=OPUS_FRAMESIZE_ARG;
     int delayed_decision=0;
+    int ret = EXIT_FAILURE;
 
     if (argc < 5 )
     {
        print_usage( argv );
-       return EXIT_FAILURE;
+       goto failure;
     }
 
     tot_in=tot_out=0;
@@ -291,7 +287,7 @@
     if (!decode_only && argc < 7 )
     {
        print_usage( argv );
-       return EXIT_FAILURE;
+       goto failure;
     }
 
     if (!decode_only)
@@ -303,7 +299,7 @@
        else if (strcmp(argv[args], "audio")!=0) {
           fprintf(stderr, "unknown application: %s\n", argv[args]);
           print_usage(argv);
-          return EXIT_FAILURE;
+          goto failure;
        }
        args++;
     }
@@ -316,7 +312,7 @@
     {
         fprintf(stderr, "Supported sampling rates are 8000, 12000, "
                 "16000, 24000 and 48000.\n");
-        return EXIT_FAILURE;
+        goto failure;
     }
     frame_size = sampling_rate/50;
 
@@ -326,7 +322,7 @@
     if (channels < 1 || channels > 2)
     {
         fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
-        return EXIT_FAILURE;
+        goto failure;
     }
 
     if (!decode_only)
@@ -366,7 +362,7 @@
                 fprintf(stderr, "Unknown bandwidth %s. "
                                 "Supported are NB, MB, WB, SWB, FB.\n",
                                 argv[ args + 1 ]);
-                return EXIT_FAILURE;
+                goto failure;
             }
             args += 2;
         } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
@@ -393,7 +389,7 @@
                 fprintf(stderr, "Unsupported frame size: %s ms. "
                                 "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n",
                                 argv[ args + 1 ]);
-                return EXIT_FAILURE;
+                goto failure;
             }
             args += 2;
         } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
@@ -480,7 +476,7 @@
         } else {
             printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
             print_usage( argv );
-            return EXIT_FAILURE;
+            goto failure;
         }
     }
 
@@ -491,7 +487,7 @@
     {
         fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
                           MAX_PACKET);
-        return EXIT_FAILURE;
+        goto failure;
     }
 
     inFile = argv[argc-2];
@@ -499,7 +495,7 @@
     if (!fin)
     {
         fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
-        return EXIT_FAILURE;
+        goto failure;
     }
     if (mode_list)
     {
@@ -517,8 +513,7 @@
     if (!fout)
     {
         fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
-        fclose(fin);
-        return EXIT_FAILURE;
+        goto failure;
     }
 
     if (!decode_only)
@@ -527,9 +522,7 @@
        if (err != OPUS_OK)
        {
           fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
-          fclose(fin);
-          fclose(fout);
-          return EXIT_FAILURE;
+          goto failure;
        }
        opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
        opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
@@ -551,9 +544,7 @@
        if (err != OPUS_OK)
        {
           fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
-          fclose(fin);
-          fclose(fout);
-          return EXIT_FAILURE;
+          goto failure;
        }
     }
 
@@ -729,9 +720,7 @@
             if (len[toggle] < 0)
             {
                 fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
-                fclose(fin);
-                fclose(fout);
-                return EXIT_FAILURE;
+                goto failure;
             }
             curr_mode_count += frame_size;
             if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
@@ -748,7 +737,7 @@
            if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
            {
               fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
-              return EXIT_FAILURE;
+              goto failure;
            }
            len[toggle] = new_len;
         }
@@ -759,16 +748,16 @@
             int_to_char(len[toggle], int_field);
             if (fwrite(int_field, 1, 4, fout) != 4) {
                fprintf(stderr, "Error writing.\n");
-               return EXIT_FAILURE;
+               goto failure;
             }
             int_to_char(enc_final_range[toggle], int_field);
             if (fwrite(int_field, 1, 4, fout) != 4) {
                fprintf(stderr, "Error writing.\n");
-               return EXIT_FAILURE;
+               goto failure;
             }
             if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
                fprintf(stderr, "Error writing.\n");
-               return EXIT_FAILURE;
+               goto failure;
             }
             tot_samples += nb_encoded;
         } else {
@@ -811,7 +800,7 @@
                        }
                        if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
                           fprintf(stderr, "Error writing.\n");
-                          return EXIT_FAILURE;
+                          goto failure;
                        }
                        tot_out += output_samples-skip;
                     }
@@ -837,9 +826,7 @@
                          (long)count,
                          (unsigned long)enc_final_range[toggle^use_inbandfec],
                          (unsigned long)dec_final_range);
-            fclose(fin);
-            fclose(fout);
-            return EXIT_FAILURE;
+            goto failure;
         }
 
         lost_prev = lost;
@@ -865,29 +852,41 @@
         toggle = (toggle + use_inbandfec) & 1;
     }
 
-    /* Print out bitrate statistics */
-    if(decode_only)
+    if(decode_only && count > 0)
         frame_size = (int)(tot_samples / count);
     count -= use_inbandfec;
-    fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
-                     1e-3*bits*sampling_rate/tot_samples);
-    fprintf (stderr, "maximum bitrate:             %7.3f kb/s\n",
-                     1e-3*bits_max*sampling_rate/frame_size);
-    if (!decode_only)
-       fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
-               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);
+    if (tot_samples >= 1 && count > 0 && frame_size)
+    {
+       /* Print out bitrate statistics */
+       double var;
+       fprintf (stderr, "average bitrate:             %7.3f kb/s\n",
+                        1e-3*bits*sampling_rate/tot_samples);
+       fprintf (stderr, "maximum bitrate:             %7.3f kb/s\n",
+                        1e-3*bits_max*sampling_rate/frame_size);
+       if (!decode_only)
+          fprintf (stderr, "active bitrate:              %7.3f kb/s\n",
+                           1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act));
+       var = bits2/count - bits*bits/(count*(double)count);
+       if (var < 0)
+          var = 0;
+       fprintf (stderr, "bitrate standard deviation:  %7.3f kb/s\n",
+                        1e-3*sqrt(var)*sampling_rate/frame_size);
+    } else {
+       fprintf(stderr, "bitrate statistics are undefined\n");
+    }
     silk_TimerSave("opus_timing.txt");
+    ret = EXIT_SUCCESS;
+failure:
     opus_encoder_destroy(enc);
     opus_decoder_destroy(dec);
     free(data[0]);
-    if (use_inbandfec)
-        free(data[1]);
-    fclose(fin);
-    fclose(fout);
+    free(data[1]);
+    if (fin)
+        fclose(fin);
+    if (fout)
+        fclose(fout);
     free(in);
     free(out);
     free(fbytes);
-    return EXIT_SUCCESS;
+    return ret;
 }
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 474e6c2..1c5a8b3 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -123,38 +123,38 @@
    middle (memoriless) threshold. The second column is the hysteresis
    (difference with the middle) */
 static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
-        10000, 1000, /* NB<->MB */
-        11000, 1000, /* MB<->WB */
+         9000,  700, /* NB<->MB */
+         9000,  700, /* MB<->WB */
         13500, 1000, /* WB<->SWB */
         14000, 2000, /* SWB<->FB */
 };
 static const opus_int32 mono_music_bandwidth_thresholds[8] = {
-        10000, 1000, /* NB<->MB */
-        11000, 1000, /* MB<->WB */
-        13500, 1000, /* WB<->SWB */
-        14000, 2000, /* SWB<->FB */
+         9000,  700, /* NB<->MB */
+         9000,  700, /* MB<->WB */
+        11000, 1000, /* WB<->SWB */
+        12000, 2000, /* SWB<->FB */
 };
 static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
-        10000, 1000, /* NB<->MB */
-        11000, 1000, /* MB<->WB */
+         9000,  700, /* NB<->MB */
+         9000,  700, /* MB<->WB */
         13500, 1000, /* WB<->SWB */
         14000, 2000, /* SWB<->FB */
 };
 static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
-        10000, 1000, /* NB<->MB */
-        11000, 1000, /* MB<->WB */
-        13500, 1000, /* WB<->SWB */
-        14000, 2000, /* SWB<->FB */
+         9000,  700, /* NB<->MB */
+         9000,  700, /* MB<->WB */
+        11000, 1000, /* WB<->SWB */
+        12000, 2000, /* SWB<->FB */
 };
 /* Threshold bit-rates for switching between mono and stereo */
-static const opus_int32 stereo_voice_threshold = 24000;
-static const opus_int32 stereo_music_threshold = 24000;
+static const opus_int32 stereo_voice_threshold = 19000;
+static const opus_int32 stereo_music_threshold = 17000;
 
 /* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
 static const opus_int32 mode_thresholds[2][2] = {
       /* voice */ /* music */
-      {  64000,      16000}, /* mono */
-      {  36000,      16000}, /* stereo */
+      {  64000,      10000}, /* mono */
+      {  44000,      10000}, /* stereo */
 };
 
 static const opus_int32 fec_thresholds[] = {
@@ -385,20 +385,16 @@
    int c, i;
    int shift;
 
-   /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */
-   shift=celt_ilog2(Fs/(cutoff_Hz*3));
+   /* Approximates -round(log2(6.3*cutoff_Hz/Fs)) */
+   shift=celt_ilog2(Fs/(cutoff_Hz*4));
    for (c=0;c<channels;c++)
    {
       for (i=0;i<len;i++)
       {
-         opus_val32 x, tmp, y;
+         opus_val32 x, y;
          x = SHL32(EXTEND32(in[channels*i+c]), 14);
-         /* First stage */
-         tmp = x-hp_mem[2*c];
+         y = 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, 14), 32767));
       }
    }
@@ -409,55 +405,39 @@
 {
    int i;
    float coef, coef2;
-   coef = 4.0f*cutoff_Hz/Fs;
+   coef = 6.3f*cutoff_Hz/Fs;
    coef2 = 1-coef;
    if (channels==2)
    {
-      float m0, m1, m2, m3;
+      float m0, m2;
       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;
+         opus_val32 x0, x1, out0, out1;
          x0 = in[2*i+0];
          x1 = in[2*i+1];
-         /* First stage */
-         tmp0 = x0-m0;
-         tmp1 = x1-m2;
+         out0 = x0-m0;
+         out1 = 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;
+      float m0;
       m0 = hp_mem[0];
-      m1 = hp_mem[1];
       for (i=0;i<len;i++)
       {
-         opus_val32 x, tmp, y;
+         opus_val32 x, y;
          x = in[i];
-         /* First stage */
-         tmp = x-m0;
+         y = x-m0;
          m0 = coef*x + VERY_SMALL + coef2*m0;
-         /* Second stage */
-         y = tmp - m1;
-         m1 = coef*tmp + VERY_SMALL + coef2*m1;
          out[i] = y;
       }
       hp_mem[0] = m0;
-      hp_mem[1] = m1;
    }
 }
 #endif
@@ -699,6 +679,12 @@
       xy += SHR32(pxy, 10);
       yy += SHR32(pyy, 10);
    }
+#ifndef FIXED_POINT
+   if (!(xx < 1e9f) || celt_isnan(xx) || !(yy < 1e9f) || celt_isnan(yy))
+   {
+      xy = xx = yy = 0;
+   }
+#endif
    mem->XX += MULT16_32_Q15(short_alpha, xx-mem->XX);
    mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY);
    mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY);
@@ -762,7 +748,7 @@
    return 0;
 }
 
-static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec) {
+static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) {
    int entry;
    int i;
    int N;
@@ -779,6 +765,8 @@
       {32000, 22000, 22000, 28000, 28000},
       {64000, 38000, 38000, 50000, 50000}
    };
+   /* Do the allocation per-channel. */
+   rate /= channels;
    entry = 1 + frame20ms + 2*fec;
    N = sizeof(rate_table)/sizeof(rate_table[0]);
    for (i=1;i<N;i++)
@@ -805,6 +793,10 @@
    }
    if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND)
       silk_rate += 300;
+   silk_rate *= channels;
+   /* Small adjustment for stereo (calibrated for 32 kb/s, haven't tried other bitrates). */
+   if (channels == 2 && rate >= 12000)
+      silk_rate -= 1000;
    return silk_rate;
 }
 
@@ -816,7 +808,8 @@
    opus_int32 equiv;
    equiv = bitrate;
    /* Take into account overhead from smaller frames. */
-   equiv -= (40*channels+20)*(frame_rate - 50);
+   if (frame_rate > 50)
+      equiv -= (40*channels+20)*(frame_rate - 50);
    /* CBR is about a 8% penalty for both SILK and CELT. */
    if (!vbr)
       equiv -= equiv/12;
@@ -909,21 +902,20 @@
                            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)
+      if (activity_probability < DTX_ACTIVITY_THRESHOLD)  /* is noise */
       {
          noise_energy = compute_frame_energy(pcm, frame_size, channels, arch);
-         is_sufficiently_quiet = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy);
+
+         /* but is sufficiently quiet */
+         is_silence = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy);
       }
    }
 
-   if (is_silence || (is_noise && is_sufficiently_quiet))
+   if (is_silence)
    {
       /* The number of consecutive DTX frames should be within the allowed bounds */
       (*nb_no_activity_frames)++;
@@ -1184,7 +1176,16 @@
     {
        int analysis_bandwidth;
        if (st->signal_type == OPUS_AUTO)
-          st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));
+       {
+          float prob;
+          if (st->prev_mode == 0)
+             prob = analysis_info.music_prob;
+          else if (st->prev_mode == MODE_CELT_ONLY)
+             prob = analysis_info.music_prob_max;
+          else
+             prob = analysis_info.music_prob_min;
+          st->voice_ratio = (int)floor(.5+100*(1-prob));
+       }
 
        analysis_bandwidth = analysis_info.bandwidth;
        if (analysis_bandwidth<=12)
@@ -1486,6 +1487,10 @@
             if (equiv_rate >= threshold)
                 break;
         } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
+        /* We don't use mediumband anymore, except when explicitly requested or during
+           mode transitions. */
+        if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
+           bandwidth = OPUS_BANDWIDTH_WIDEBAND;
         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 */
@@ -1599,7 +1604,8 @@
        redundancy = 1;
        celt_to_silk = 1;
        st->silk_bw_switch = 0;
-       prefill=1;
+       /* Do a prefill without reseting the sampling rate control. */
+       prefill=2;
     }
 
     /* If we decided to go with CELT, make sure redundancy is off, no matter what
@@ -1662,6 +1668,7 @@
     if (st->mode != MODE_CELT_ONLY)
     {
         opus_int32 total_bitRate, celt_rate;
+        opus_int activity;
 #ifdef FIXED_POINT
        const opus_int16 *pcm_silk;
 #else
@@ -1669,12 +1676,21 @@
        ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
 #endif
 
+        activity = VAD_NO_DECISION;
+#ifndef DISABLE_FLOAT_API
+        if( analysis_info.valid ) {
+            /* Inform SILK about the Opus VAD decision */
+            activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD );
+        }
+#endif
+
         /* Distribute bits between SILK and CELT */
         total_bitRate = 8 * bytes_target * frame_rate;
         if( st->mode == MODE_HYBRID ) {
             /* Base rate for SILK */
             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);
+                  curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
+                  st->stream_channels);
             if (!st->energy_masking)
             {
                /* Increasingly attenuate high band when it gets allocated fewer bits */
@@ -1736,7 +1752,7 @@
         } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
             st->silk_mode.desiredInternalSampleRate = 12000;
         } else {
-            silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
+            celt_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
             st->silk_mode.desiredInternalSampleRate = 16000;
         }
         if( st->mode == MODE_HYBRID ) {
@@ -1789,7 +1805,8 @@
            {
               /* 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);
+                    curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
+                    st->stream_channels);
               st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
            }
         }
@@ -1814,7 +1831,9 @@
             for (i=0;i<st->encoder_buffer*st->channels;i++)
                 pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
 #endif
-            silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 );
+            silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, prefill, activity );
+            /* Prevent a second switch in the real encode call. */
+            st->silk_mode.opusCanSwitch = 0;
         }
 
 #ifdef FIXED_POINT
@@ -1823,7 +1842,7 @@
         for (i=0;i<frame_size*st->channels;i++)
             pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);
 #endif
-        ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
+        ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0, activity );
         if( ret ) {
             /*fprintf (stderr, "SILK encode error: %d\n", ret);*/
             /* Handle error */
@@ -1841,7 +1860,7 @@
                curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
             }
         } else {
-            silk_assert( st->silk_mode.internalSampleRate == 16000 );
+            celt_assert( st->silk_mode.internalSampleRate == 16000 );
         }
 
         st->silk_mode.opusCanSwitch = st->silk_mode.switchReady && !st->nonfinal_frame;
@@ -1936,7 +1955,14 @@
     }
     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-24000));
+    {
+       if (equiv_rate > 32000)
+          st->silk_mode.stereoWidth_Q14 = 16384;
+       else if (equiv_rate < 16000)
+          st->silk_mode.stereoWidth_Q14 = 0;
+       else
+          st->silk_mode.stereoWidth_Q14 = 16384 - 2048*(opus_int32)(32000-equiv_rate)/(equiv_rate-14000);
+    }
     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) ) {
@@ -2010,8 +2036,6 @@
        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 */
diff --git a/src/opus_multistream_decoder.c b/src/opus_multistream_decoder.c
index e421726..562103c 100644
--- a/src/opus_multistream_decoder.c
+++ b/src/opus_multistream_decoder.c
@@ -37,16 +37,19 @@
 #include "float_cast.h"
 #include "os_support.h"
 
-struct OpusMSDecoder {
-   ChannelLayout layout;
-   /* Decoder states go here */
-};
-
-
-
-
 /* DECODER */
 
+#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
+static void validate_ms_decoder(OpusMSDecoder *st)
+{
+   validate_layout(&st->layout);
+}
+#define VALIDATE_MS_DECODER(st) validate_ms_decoder(st)
+#else
+#define VALIDATE_MS_DECODER(st)
+#endif
+
+
 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
 {
    int coupled_size;
@@ -143,15 +146,6 @@
    return st;
 }
 
-typedef void (*opus_copy_channel_out_func)(
-  void *dst,
-  int dst_stride,
-  int dst_channel,
-  const opus_val16 *src,
-  int src_stride,
-  int frame_size
-);
-
 static int opus_multistream_packet_validate(const unsigned char *data,
       opus_int32 len, int nb_streams, opus_int32 Fs)
 {
@@ -181,7 +175,7 @@
    return samples;
 }
 
-static int opus_multistream_decode_native(
+int opus_multistream_decode_native(
       OpusMSDecoder *st,
       const unsigned char *data,
       opus_int32 len,
@@ -189,7 +183,8 @@
       opus_copy_channel_out_func copy_channel_out,
       int frame_size,
       int decode_fec,
-      int soft_clip
+      int soft_clip,
+      void *user_data
 )
 {
    opus_int32 Fs;
@@ -201,8 +196,14 @@
    VARDECL(opus_val16, buf);
    ALLOC_STACK;
 
+   VALIDATE_MS_DECODER(st);
+   if (frame_size <= 0)
+   {
+      RESTORE_STACK;
+      return OPUS_BAD_ARG;
+   }
    /* Limit frame_size to avoid excessive stack allocations. */
-   opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
+   MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)));
    frame_size = IMIN(frame_size, Fs/25*3);
    ALLOC(buf, 2*frame_size, opus_val16);
    ptr = (char*)st + align(sizeof(OpusMSDecoder));
@@ -266,7 +267,7 @@
          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
          {
             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
-               buf, 2, frame_size);
+               buf, 2, frame_size, user_data);
             prev = chan;
          }
          prev = -1;
@@ -274,7 +275,7 @@
          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
          {
             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
-               buf+1, 2, frame_size);
+               buf+1, 2, frame_size, user_data);
             prev = chan;
          }
       } else {
@@ -284,7 +285,7 @@
          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
          {
             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
-               buf, 1, frame_size);
+               buf, 1, frame_size, user_data);
             prev = chan;
          }
       }
@@ -295,7 +296,7 @@
       if (st->layout.mapping[c] == 255)
       {
          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
-            NULL, 0, frame_size);
+            NULL, 0, frame_size, user_data);
       }
    }
    RESTORE_STACK;
@@ -309,11 +310,13 @@
   int dst_channel,
   const opus_val16 *src,
   int src_stride,
-  int frame_size
+  int frame_size,
+  void *user_data
 )
 {
    float *float_dst;
    opus_int32 i;
+   (void)user_data;
    float_dst = (float*)dst;
    if (src != NULL)
    {
@@ -338,11 +341,13 @@
   int dst_channel,
   const opus_val16 *src,
   int src_stride,
-  int frame_size
+  int frame_size,
+  void *user_data
 )
 {
    opus_int16 *short_dst;
    opus_int32 i;
+   (void)user_data;
    short_dst = (opus_int16*)dst;
    if (src != NULL)
    {
@@ -373,7 +378,7 @@
 )
 {
    return opus_multistream_decode_native(st, data, len,
-       pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0);
+       pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0, NULL);
 }
 
 #ifndef DISABLE_FLOAT_API
@@ -381,7 +386,7 @@
       opus_int32 len, float *pcm, int frame_size, int decode_fec)
 {
    return opus_multistream_decode_native(st, data, len,
-       pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
+       pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
 }
 #endif
 
@@ -391,32 +396,30 @@
       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
 {
    return opus_multistream_decode_native(st, data, len,
-       pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1);
+       pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1, NULL);
 }
 
 int opus_multistream_decode_float(
       OpusMSDecoder *st,
       const unsigned char *data,
       opus_int32 len,
-      float *pcm,
+      opus_val16 *pcm,
       int frame_size,
       int decode_fec
 )
 {
    return opus_multistream_decode_native(st, data, len,
-       pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
+       pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
 }
 #endif
 
-int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
+int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
+                                         va_list ap)
 {
-   va_list ap;
    int coupled_size, mono_size;
    char *ptr;
    int ret = OPUS_OK;
 
-   va_start(ap, request);
-
    coupled_size = opus_decoder_get_size(2);
    mono_size = opus_decoder_get_size(1);
    ptr = (char*)st + align(sizeof(OpusMSDecoder));
@@ -525,14 +528,20 @@
           ret = OPUS_UNIMPLEMENTED;
        break;
    }
-
-   va_end(ap);
    return ret;
 bad_arg:
-   va_end(ap);
    return OPUS_BAD_ARG;
 }
 
+int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
+{
+   int ret;
+   va_list ap;
+   va_start(ap, request);
+   ret = opus_multistream_decoder_ctl_va_list(st, request, ap);
+   va_end(ap);
+   return ret;
+}
 
 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
 {
diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c
index 032fc00..9cb9bf3 100644
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -61,37 +61,6 @@
       {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
 };
 
-typedef void (*opus_copy_channel_in_func)(
-  opus_val16 *dst,
-  int dst_stride,
-  const void *src,
-  int src_stride,
-  int src_channel,
-  int frame_size
-);
-
-typedef enum {
-  MAPPING_TYPE_NONE,
-  MAPPING_TYPE_SURROUND
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
-  ,  /* Do not include comma at end of enumerator list */
-  MAPPING_TYPE_AMBISONICS
-#endif
-} MappingType;
-
-struct OpusMSEncoder {
-   ChannelLayout layout;
-   int arch;
-   int lfe_stream;
-   int application;
-   int variable_duration;
-   MappingType mapping_type;
-   opus_int32 bitrate_bps;
-   /* Encoder states go here */
-   /* then opus_val32 window_mem[channels*120]; */
-   /* then opus_val32 preemph_mem[channels]; */
-};
-
 static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
 {
    int s;
@@ -132,19 +101,20 @@
    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;
 
+   if (nb_channels < 1 || nb_channels > 227)
+      return 0;
+
    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))
+   if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
       return 0;
 
    if (nb_streams)
@@ -153,7 +123,6 @@
       *nb_coupled_streams = nondiegetic_channels != 0;
    return 1;
 }
-#endif
 
 static int validate_encoder_layout(const ChannelLayout *layout)
 {
@@ -296,7 +265,7 @@
       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);
+      (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
       celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
 #ifndef FIXED_POINT
       {
@@ -443,12 +412,10 @@
    {
       nb_streams=channels;
       nb_coupled_streams=0;
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
-   } else if (mapping_family==254)
+   } else if (mapping_family==2)
    {
       if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
          return 0;
-#endif
    } else
       return 0;
    size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
@@ -495,11 +462,9 @@
    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);
@@ -591,8 +556,7 @@
       *coupled_streams=0;
       for(i=0;i<channels;i++)
          mapping[i] = i;
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
-   } else if (mapping_family==254)
+   } else if (mapping_family==2)
    {
       int i;
       if (!validate_ambisonics(channels, streams, coupled_streams))
@@ -601,17 +565,14 @@
          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;
 
    if (channels>2 && mapping_family==1) {
       mapping_type = MAPPING_TYPE_SURROUND;
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
-   } else if (mapping_family==254)
+   } else if (mapping_family==2)
    {
       mapping_type = MAPPING_TYPE_AMBISONICS;
-#endif
    } else
    {
       mapping_type = MAPPING_TYPE_NONE;
@@ -772,7 +733,6 @@
    }
 }
 
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
 static void ambisonics_rate_allocation(
       OpusMSEncoder *st,
       opus_int32 *rate,
@@ -781,24 +741,15 @@
       )
 {
    int i;
-   int total_rate;
-   int directional_rate;
-   int nondirectional_rate;
-   int leftover_bits;
+   opus_int32 total_rate;
+   opus_int32 per_stream_rate;
 
-   /* 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 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 = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
-         (Fs+60*Fs/frame_size) + st->layout.nb_streams * 15000;
+         (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000;
    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
    {
       total_rate = nb_channels * 320000;
@@ -807,49 +758,14 @@
       total_rate = st->bitrate_bps;
    }
 
-   /* 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
-    *   T = (n - m) * y + m * m_rate
-    * Solving for y,
-    *   y = (q * T) / (m * (p - q) + n * q)
-    */
-   directional_rate =
-      total_rate * rate_ratio_den
-      / (nb_nondirectional_channels * (rate_ratio_num - rate_ratio_den)
-       + nb_channels * rate_ratio_den);
-
-   /* Calculate the nondirectional rate.
-    *   m_rate = y * (p / q)
-    */
-   nondirectional_rate = directional_rate * rate_ratio_num / rate_ratio_den;
-
-   /* 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 */
+   /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic
+    * (coupled) streams */
+   per_stream_rate = total_rate / st->layout.nb_streams;
    for (i = 0; i < st->layout.nb_streams; i++)
    {
-      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;
-      }
+     rate[i] = per_stream_rate;
    }
 }
-#endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
 
 static opus_int32 rate_allocation(
       OpusMSEncoder *st,
@@ -865,11 +781,9 @@
    ptr = (char*)st + align(sizeof(OpusMSEncoder));
    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
 
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
    if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
      ambisonics_rate_allocation(st, rate, frame_size, Fs);
    } else
-#endif
    {
      surround_rate_allocation(st, rate, frame_size, Fs);
    }
@@ -884,7 +798,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
+int opus_multistream_encode_native
 (
     OpusMSEncoder *st,
     opus_copy_channel_in_func copy_channel_in,
@@ -894,7 +808,8 @@
     opus_int32 max_data_bytes,
     int lsb_depth,
     downmix_func downmix,
-    int float_api
+    int float_api,
+    void *user_data
 )
 {
    opus_int32 Fs;
@@ -1001,11 +916,9 @@
             opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
          }
       }
-#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
       else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
         opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
       }
-#endif
    }
 
    ptr = (char*)st + align(sizeof(OpusMSEncoder));
@@ -1028,9 +941,9 @@
          left = get_left_channel(&st->layout, s, -1);
          right = get_right_channel(&st->layout, s, -1);
          (*copy_channel_in)(buf, 2,
-            pcm, st->layout.nb_channels, left, frame_size);
+            pcm, st->layout.nb_channels, left, frame_size, user_data);
          (*copy_channel_in)(buf+1, 2,
-            pcm, st->layout.nb_channels, right, frame_size);
+            pcm, st->layout.nb_channels, right, frame_size, user_data);
          ptr += align(coupled_size);
          if (st->mapping_type == MAPPING_TYPE_SURROUND)
          {
@@ -1046,7 +959,7 @@
          int i;
          int chan = get_mono_channel(&st->layout, s, -1);
          (*copy_channel_in)(buf, 1,
-            pcm, st->layout.nb_channels, chan, frame_size);
+            pcm, st->layout.nb_channels, chan, frame_size, user_data);
          ptr += align(mono_size);
          if (st->mapping_type == MAPPING_TYPE_SURROUND)
          {
@@ -1105,11 +1018,13 @@
   const void *src,
   int src_stride,
   int src_channel,
-  int frame_size
+  int frame_size,
+  void *user_data
 )
 {
    const float *float_src;
    opus_int32 i;
+   (void)user_data;
    float_src = (const float *)src;
    for (i=0;i<frame_size;i++)
 #if defined(FIXED_POINT)
@@ -1126,11 +1041,13 @@
   const void *src,
   int src_stride,
   int src_channel,
-  int frame_size
+  int frame_size,
+  void *user_data
 )
 {
    const opus_int16 *short_src;
    opus_int32 i;
+   (void)user_data;
    short_src = (const opus_int16 *)src;
    for (i=0;i<frame_size;i++)
 #if defined(FIXED_POINT)
@@ -1151,7 +1068,7 @@
 )
 {
    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
-      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
+      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
 }
 
 #ifndef DISABLE_FLOAT_API
@@ -1164,7 +1081,7 @@
 )
 {
    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
-      pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
+      pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, NULL);
 }
 #endif
 
@@ -1180,7 +1097,7 @@
 )
 {
    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
-      pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
+      pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, NULL);
 }
 
 int opus_multistream_encode(
@@ -1192,19 +1109,17 @@
 )
 {
    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
-      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
+      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
 }
 #endif
 
-int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
+int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
+                                         va_list ap)
 {
-   va_list ap;
    int coupled_size, mono_size;
    char *ptr;
    int ret = OPUS_OK;
 
-   va_start(ap, request);
-
    coupled_size = opus_encoder_get_size(2);
    mono_size = opus_encoder_get_size(1);
    ptr = (char*)st + align(sizeof(OpusMSEncoder));
@@ -1392,14 +1307,21 @@
       ret = OPUS_UNIMPLEMENTED;
       break;
    }
-
-   va_end(ap);
    return ret;
 bad_arg:
-   va_end(ap);
    return OPUS_BAD_ARG;
 }
 
+int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
+{
+   int ret;
+   va_list ap;
+   va_start(ap, request);
+   ret = opus_multistream_encoder_ctl_va_list(st, request, ap);
+   va_end(ap);
+   return ret;
+}
+
 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
 {
     opus_free(st);
diff --git a/src/opus_private.h b/src/opus_private.h
index a731cc5..09783ce 100644
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -33,6 +33,7 @@
 #include "opus.h"
 #include "celt.h"
 
+#include <stdarg.h> /* va_list */
 #include <stddef.h> /* offsetof */
 
 struct OpusRepacketizer {
@@ -50,12 +51,59 @@
    unsigned char mapping[256];
 } ChannelLayout;
 
+typedef enum {
+  MAPPING_TYPE_NONE,
+  MAPPING_TYPE_SURROUND,
+  MAPPING_TYPE_AMBISONICS
+} MappingType;
+
+struct OpusMSEncoder {
+   ChannelLayout layout;
+   int arch;
+   int lfe_stream;
+   int application;
+   int variable_duration;
+   MappingType mapping_type;
+   opus_int32 bitrate_bps;
+   /* Encoder states go here */
+   /* then opus_val32 window_mem[channels*120]; */
+   /* then opus_val32 preemph_mem[channels]; */
+};
+
+struct OpusMSDecoder {
+   ChannelLayout layout;
+   /* Decoder states go here */
+};
+
+int opus_multistream_encoder_ctl_va_list(struct OpusMSEncoder *st, int request,
+  va_list ap);
+int opus_multistream_decoder_ctl_va_list(struct OpusMSDecoder *st, int request,
+  va_list ap);
+
 int validate_layout(const ChannelLayout *layout);
 int get_left_channel(const ChannelLayout *layout, int stream_id, int prev);
 int get_right_channel(const ChannelLayout *layout, int stream_id, int prev);
 int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);
 
+typedef void (*opus_copy_channel_in_func)(
+  opus_val16 *dst,
+  int dst_stride,
+  const void *src,
+  int src_stride,
+  int src_channel,
+  int frame_size,
+  void *user_data
+);
 
+typedef void (*opus_copy_channel_out_func)(
+  void *dst,
+  int dst_stride,
+  int dst_channel,
+  const opus_val16 *src,
+  int src_stride,
+  int frame_size,
+  void *user_data
+);
 
 #define MODE_SILK_ONLY          1000
 #define MODE_HYBRID             1001
@@ -123,4 +171,30 @@
 
 int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len);
 
+int opus_multistream_encode_native
+(
+  struct OpusMSEncoder *st,
+  opus_copy_channel_in_func copy_channel_in,
+  const void *pcm,
+  int analysis_frame_size,
+  unsigned char *data,
+  opus_int32 max_data_bytes,
+  int lsb_depth,
+  downmix_func downmix,
+  int float_api,
+  void *user_data
+);
+
+int opus_multistream_decode_native(
+  struct OpusMSDecoder *st,
+  const unsigned char *data,
+  opus_int32 len,
+  void *pcm,
+  opus_copy_channel_out_func copy_channel_out,
+  int frame_size,
+  int decode_fec,
+  int soft_clip,
+  void *user_data
+);
+
 #endif /* OPUS_PRIVATE_H */
diff --git a/src/opus_projection_decoder.c b/src/opus_projection_decoder.c
new file mode 100644
index 0000000..c2e07d5
--- /dev/null
+++ b/src/opus_projection_decoder.c
@@ -0,0 +1,258 @@
+/* Copyright (c) 2017 Google Inc.
+   Written by Andrew Allen */
+/*
+   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 "mathops.h"
+#include "os_support.h"
+#include "opus_private.h"
+#include "opus_defines.h"
+#include "opus_projection.h"
+#include "opus_multistream.h"
+#include "mapping_matrix.h"
+#include "stack_alloc.h"
+
+struct OpusProjectionDecoder
+{
+  opus_int32 demixing_matrix_size_in_bytes;
+  /* Encoder states go here */
+};
+
+#if !defined(DISABLE_FLOAT_API)
+static void opus_projection_copy_channel_out_float(
+  void *dst,
+  int dst_stride,
+  int dst_channel,
+  const opus_val16 *src,
+  int src_stride,
+  int frame_size,
+  void *user_data)
+{
+  float *float_dst;
+  const MappingMatrix *matrix;
+  float_dst = (float *)dst;
+  matrix = (const MappingMatrix *)user_data;
+
+  if (dst_channel == 0)
+    OPUS_CLEAR(float_dst, frame_size * dst_stride);
+
+  if (src != NULL)
+    mapping_matrix_multiply_channel_out_float(matrix, src, dst_channel,
+      src_stride, float_dst, dst_stride, frame_size);
+}
+#endif
+
+static void opus_projection_copy_channel_out_short(
+  void *dst,
+  int dst_stride,
+  int dst_channel,
+  const opus_val16 *src,
+  int src_stride,
+  int frame_size,
+  void *user_data)
+{
+  opus_int16 *short_dst;
+  const MappingMatrix *matrix;
+  short_dst = (opus_int16 *)dst;
+  matrix = (const MappingMatrix *)user_data;
+  if (dst_channel == 0)
+    OPUS_CLEAR(short_dst, frame_size * dst_stride);
+
+  if (src != NULL)
+    mapping_matrix_multiply_channel_out_short(matrix, src, dst_channel,
+      src_stride, short_dst, dst_stride, frame_size);
+}
+
+static MappingMatrix *get_dec_demixing_matrix(OpusProjectionDecoder *st)
+{
+  /* void* cast avoids clang -Wcast-align warning */
+  return (MappingMatrix*)(void*)((char*)st +
+    align(sizeof(OpusProjectionDecoder)));
+}
+
+static OpusMSDecoder *get_multistream_decoder(OpusProjectionDecoder *st)
+{
+  /* void* cast avoids clang -Wcast-align warning */
+  return (OpusMSDecoder*)(void*)((char*)st +
+    align(sizeof(OpusProjectionDecoder) +
+    st->demixing_matrix_size_in_bytes));
+}
+
+opus_int32 opus_projection_decoder_get_size(int channels, int streams,
+                                            int coupled_streams)
+{
+  opus_int32 matrix_size;
+  opus_int32 decoder_size;
+
+  matrix_size =
+    mapping_matrix_get_size(streams + coupled_streams, channels);
+  if (!matrix_size)
+    return 0;
+
+  decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams);
+  if (!decoder_size)
+    return 0;
+
+  return align(sizeof(OpusProjectionDecoder)) + matrix_size + decoder_size;
+}
+
+int opus_projection_decoder_init(OpusProjectionDecoder *st, opus_int32 Fs,
+  int channels, int streams, int coupled_streams,
+  unsigned char *demixing_matrix, opus_int32 demixing_matrix_size)
+{
+  int nb_input_streams;
+  opus_int32 expected_matrix_size;
+  int i, ret;
+  unsigned char mapping[255];
+  VARDECL(opus_int16, buf);
+  ALLOC_STACK;
+
+  /* Verify supplied matrix size. */
+  nb_input_streams = streams + coupled_streams;
+  expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16);
+  if (expected_matrix_size != demixing_matrix_size)
+  {
+    RESTORE_STACK;
+    return OPUS_BAD_ARG;
+  }
+
+  /* Convert demixing matrix input into internal format. */
+  ALLOC(buf, nb_input_streams * channels, opus_int16);
+  for (i = 0; i < nb_input_streams * channels; i++)
+  {
+    int s = demixing_matrix[2*i + 1] << 8 | demixing_matrix[2*i];
+    s = ((s & 0xFFFF) ^ 0x8000) - 0x8000;
+    buf[i] = (opus_int16)s;
+  }
+
+  /* Assign demixing matrix. */
+  st->demixing_matrix_size_in_bytes =
+    mapping_matrix_get_size(channels, nb_input_streams);
+  if (!st->demixing_matrix_size_in_bytes)
+  {
+    RESTORE_STACK;
+    return OPUS_BAD_ARG;
+  }
+
+  mapping_matrix_init(get_dec_demixing_matrix(st), channels, nb_input_streams, 0,
+    buf, demixing_matrix_size);
+
+  /* Set trivial mapping so each input channel pairs with a matrix column. */
+  for (i = 0; i < channels; i++)
+    mapping[i] = i;
+
+  ret = opus_multistream_decoder_init(
+    get_multistream_decoder(st), Fs, channels, streams, coupled_streams, mapping);
+  RESTORE_STACK;
+  return ret;
+}
+
+OpusProjectionDecoder *opus_projection_decoder_create(
+  opus_int32 Fs, int channels, int streams, int coupled_streams,
+  unsigned char *demixing_matrix, opus_int32 demixing_matrix_size, int *error)
+{
+  int size;
+  int ret;
+  OpusProjectionDecoder *st;
+
+  /* Allocate space for the projection decoder. */
+  size = opus_projection_decoder_get_size(channels, streams, coupled_streams);
+  if (!size) {
+    if (error)
+      *error = OPUS_ALLOC_FAIL;
+    return NULL;
+  }
+  st = (OpusProjectionDecoder *)opus_alloc(size);
+  if (!st)
+  {
+    if (error)
+      *error = OPUS_ALLOC_FAIL;
+    return NULL;
+  }
+
+  /* Initialize projection decoder with provided settings. */
+  ret = opus_projection_decoder_init(st, Fs, channels, streams, coupled_streams,
+                                     demixing_matrix, demixing_matrix_size);
+  if (ret != OPUS_OK)
+  {
+    opus_free(st);
+    st = NULL;
+  }
+  if (error)
+    *error = ret;
+  return st;
+}
+
+#ifdef FIXED_POINT
+int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
+                           opus_int32 len, opus_int16 *pcm, int frame_size,
+                           int decode_fec)
+{
+  return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
+    pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 0,
+    get_dec_demixing_matrix(st));
+}
+#else
+int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
+                           opus_int32 len, opus_int16 *pcm, int frame_size,
+                           int decode_fec)
+{
+  return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
+    pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 1,
+    get_dec_demixing_matrix(st));
+}
+#endif
+
+#ifndef DISABLE_FLOAT_API
+int opus_projection_decode_float(OpusProjectionDecoder *st, const unsigned char *data,
+                                 opus_int32 len, float *pcm, int frame_size, int decode_fec)
+{
+  return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
+    pcm, opus_projection_copy_channel_out_float, frame_size, decode_fec, 0,
+    get_dec_demixing_matrix(st));
+}
+#endif
+
+int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...)
+{
+  va_list ap;
+  int ret = OPUS_OK;
+
+  va_start(ap, request);
+  ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st),
+    request, ap);
+  va_end(ap);
+  return ret;
+}
+
+void opus_projection_decoder_destroy(OpusProjectionDecoder *st)
+{
+  opus_free(st);
+}
+
diff --git a/src/opus_projection_encoder.c b/src/opus_projection_encoder.c
new file mode 100644
index 0000000..06fb2d2
--- /dev/null
+++ b/src/opus_projection_encoder.c
@@ -0,0 +1,468 @@
+/* Copyright (c) 2017 Google Inc.
+   Written by Andrew Allen */
+/*
+   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 "mathops.h"
+#include "os_support.h"
+#include "opus_private.h"
+#include "opus_defines.h"
+#include "opus_projection.h"
+#include "opus_multistream.h"
+#include "stack_alloc.h"
+#include "mapping_matrix.h"
+
+struct OpusProjectionEncoder
+{
+  opus_int32 mixing_matrix_size_in_bytes;
+  opus_int32 demixing_matrix_size_in_bytes;
+  /* Encoder states go here */
+};
+
+#if !defined(DISABLE_FLOAT_API)
+static void opus_projection_copy_channel_in_float(
+  opus_val16 *dst,
+  int dst_stride,
+  const void *src,
+  int src_stride,
+  int src_channel,
+  int frame_size,
+  void *user_data
+)
+{
+  mapping_matrix_multiply_channel_in_float((const MappingMatrix*)user_data,
+    (const float*)src, src_stride, dst, src_channel, dst_stride, frame_size);
+}
+#endif
+
+static void opus_projection_copy_channel_in_short(
+  opus_val16 *dst,
+  int dst_stride,
+  const void *src,
+  int src_stride,
+  int src_channel,
+  int frame_size,
+  void *user_data
+)
+{
+  mapping_matrix_multiply_channel_in_short((const MappingMatrix*)user_data,
+    (const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size);
+}
+
+static int get_order_plus_one_from_channels(int channels, int *order_plus_one)
+{
+  int order_plus_one_;
+  int acn_channels;
+  int nondiegetic_channels;
+
+  /* Allowed numbers of channels:
+   * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1.
+   */
+  if (channels < 1 || channels > 227)
+    return OPUS_BAD_ARG;
+
+  order_plus_one_ = isqrt32(channels);
+  acn_channels = order_plus_one_ * order_plus_one_;
+  nondiegetic_channels = channels - acn_channels;
+  if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
+    return OPUS_BAD_ARG;
+
+  if (order_plus_one)
+    *order_plus_one = order_plus_one_;
+  return OPUS_OK;
+}
+
+static int get_streams_from_channels(int channels, int mapping_family,
+                                     int *streams, int *coupled_streams,
+                                     int *order_plus_one)
+{
+  if (mapping_family == 3)
+  {
+    if (get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK)
+      return OPUS_BAD_ARG;
+    if (streams)
+      *streams = (channels + 1) / 2;
+    if (coupled_streams)
+      *coupled_streams = channels / 2;
+    return OPUS_OK;
+  }
+  return OPUS_BAD_ARG;
+}
+
+static MappingMatrix *get_mixing_matrix(OpusProjectionEncoder *st)
+{
+  /* void* cast avoids clang -Wcast-align warning */
+  return (MappingMatrix *)(void*)((char*)st +
+    align(sizeof(OpusProjectionEncoder)));
+}
+
+static MappingMatrix *get_enc_demixing_matrix(OpusProjectionEncoder *st)
+{
+  /* void* cast avoids clang -Wcast-align warning */
+  return (MappingMatrix *)(void*)((char*)st +
+    align(sizeof(OpusProjectionEncoder) +
+    st->mixing_matrix_size_in_bytes));
+}
+
+static OpusMSEncoder *get_multistream_encoder(OpusProjectionEncoder *st)
+{
+  /* void* cast avoids clang -Wcast-align warning */
+  return (OpusMSEncoder *)(void*)((char*)st +
+    align(sizeof(OpusProjectionEncoder) +
+    st->mixing_matrix_size_in_bytes +
+    st->demixing_matrix_size_in_bytes));
+}
+
+opus_int32 opus_projection_ambisonics_encoder_get_size(int channels,
+                                                       int mapping_family)
+{
+  int nb_streams;
+  int nb_coupled_streams;
+  int order_plus_one;
+  int mixing_matrix_rows, mixing_matrix_cols;
+  int demixing_matrix_rows, demixing_matrix_cols;
+  opus_int32 mixing_matrix_size, demixing_matrix_size;
+  opus_int32 encoder_size;
+  int ret;
+
+  ret = get_streams_from_channels(channels, mapping_family, &nb_streams,
+                                  &nb_coupled_streams, &order_plus_one);
+  if (ret != OPUS_OK)
+    return 0;
+
+  if (order_plus_one == 2)
+  {
+    mixing_matrix_rows = mapping_matrix_foa_mixing.rows;
+    mixing_matrix_cols = mapping_matrix_foa_mixing.cols;
+    demixing_matrix_rows = mapping_matrix_foa_demixing.rows;
+    demixing_matrix_cols = mapping_matrix_foa_demixing.cols;
+  }
+  else if (order_plus_one == 3)
+  {
+    mixing_matrix_rows = mapping_matrix_soa_mixing.rows;
+    mixing_matrix_cols = mapping_matrix_soa_mixing.cols;
+    demixing_matrix_rows = mapping_matrix_soa_demixing.rows;
+    demixing_matrix_cols = mapping_matrix_soa_demixing.cols;
+  }
+  else if (order_plus_one == 4)
+  {
+    mixing_matrix_rows = mapping_matrix_toa_mixing.rows;
+    mixing_matrix_cols = mapping_matrix_toa_mixing.cols;
+    demixing_matrix_rows = mapping_matrix_toa_demixing.rows;
+    demixing_matrix_cols = mapping_matrix_toa_demixing.cols;
+  }
+  else
+    return 0;
+
+  mixing_matrix_size =
+    mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols);
+  if (!mixing_matrix_size)
+    return 0;
+
+  demixing_matrix_size =
+    mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols);
+  if (!demixing_matrix_size)
+    return 0;
+
+  encoder_size =
+      opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
+  if (!encoder_size)
+    return 0;
+
+  return align(sizeof(OpusProjectionEncoder)) +
+    mixing_matrix_size + demixing_matrix_size + encoder_size;
+}
+
+int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs,
+                                            int channels, int mapping_family,
+                                            int *streams, int *coupled_streams,
+                                            int application)
+{
+  MappingMatrix *mixing_matrix;
+  MappingMatrix *demixing_matrix;
+  OpusMSEncoder *ms_encoder;
+  int i;
+  int ret;
+  int order_plus_one;
+  unsigned char mapping[255];
+
+  if (streams == NULL || coupled_streams == NULL) {
+    return OPUS_BAD_ARG;
+  }
+
+  if (get_streams_from_channels(channels, mapping_family, streams,
+    coupled_streams, &order_plus_one) != OPUS_OK)
+    return OPUS_BAD_ARG;
+
+  if (mapping_family == 3)
+  {
+    /* Assign mixing matrix based on available pre-computed matrices. */
+    mixing_matrix = get_mixing_matrix(st);
+    if (order_plus_one == 2)
+    {
+      mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows,
+        mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain,
+        mapping_matrix_foa_mixing_data,
+        sizeof(mapping_matrix_foa_mixing_data));
+    }
+    else if (order_plus_one == 3)
+    {
+      mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows,
+        mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain,
+        mapping_matrix_soa_mixing_data,
+        sizeof(mapping_matrix_soa_mixing_data));
+    }
+    else if (order_plus_one == 4)
+    {
+      mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows,
+        mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain,
+        mapping_matrix_toa_mixing_data,
+        sizeof(mapping_matrix_toa_mixing_data));
+    }
+    else
+      return OPUS_BAD_ARG;
+
+    st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
+      mixing_matrix->rows, mixing_matrix->cols);
+    if (!st->mixing_matrix_size_in_bytes)
+      return OPUS_BAD_ARG;
+
+    /* Assign demixing matrix based on available pre-computed matrices. */
+    demixing_matrix = get_enc_demixing_matrix(st);
+    if (order_plus_one == 2)
+    {
+      mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows,
+        mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain,
+        mapping_matrix_foa_demixing_data,
+        sizeof(mapping_matrix_foa_demixing_data));
+    }
+    else if (order_plus_one == 3)
+    {
+      mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows,
+        mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain,
+        mapping_matrix_soa_demixing_data,
+        sizeof(mapping_matrix_soa_demixing_data));
+    }
+    else if (order_plus_one == 4)
+    {
+      mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows,
+        mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain,
+        mapping_matrix_toa_demixing_data,
+        sizeof(mapping_matrix_toa_demixing_data));
+    }
+    else
+      return OPUS_BAD_ARG;
+
+    st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
+      demixing_matrix->rows, demixing_matrix->cols);
+    if (!st->demixing_matrix_size_in_bytes)
+      return OPUS_BAD_ARG;
+  }
+  else
+    return OPUS_UNIMPLEMENTED;
+
+  /* Ensure matrices are large enough for desired coding scheme. */
+  if (*streams + *coupled_streams > mixing_matrix->rows ||
+      channels > mixing_matrix->cols ||
+      channels > demixing_matrix->rows ||
+      *streams + *coupled_streams > demixing_matrix->cols)
+    return OPUS_BAD_ARG;
+
+  /* Set trivial mapping so each input channel pairs with a matrix column. */
+  for (i = 0; i < channels; i++)
+    mapping[i] = i;
+
+  /* Initialize multistream encoder with provided settings. */
+  ms_encoder = get_multistream_encoder(st);
+  ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams,
+                                      *coupled_streams, mapping, application);
+  return ret;
+}
+
+OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
+    opus_int32 Fs, int channels, int mapping_family, int *streams,
+    int *coupled_streams, int application, int *error)
+{
+  int size;
+  int ret;
+  OpusProjectionEncoder *st;
+
+  /* Allocate space for the projection encoder. */
+  size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family);
+  if (!size) {
+    if (error)
+      *error = OPUS_ALLOC_FAIL;
+    return NULL;
+  }
+  st = (OpusProjectionEncoder *)opus_alloc(size);
+  if (!st)
+  {
+    if (error)
+      *error = OPUS_ALLOC_FAIL;
+    return NULL;
+  }
+
+  /* Initialize projection encoder with provided settings. */
+  ret = opus_projection_ambisonics_encoder_init(st, Fs, channels,
+     mapping_family, streams, coupled_streams, application);
+  if (ret != OPUS_OK)
+  {
+    opus_free(st);
+    st = NULL;
+  }
+  if (error)
+    *error = ret;
+  return st;
+}
+
+int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm,
+                           int frame_size, unsigned char *data,
+                           opus_int32 max_data_bytes)
+{
+  return opus_multistream_encode_native(get_multistream_encoder(st),
+    opus_projection_copy_channel_in_short, pcm, frame_size, data,
+    max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st));
+}
+
+#ifndef DISABLE_FLOAT_API
+#ifdef FIXED_POINT
+int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
+                                 int frame_size, unsigned char *data,
+                                 opus_int32 max_data_bytes)
+{
+  return opus_multistream_encode_native(get_multistream_encoder(st),
+    opus_projection_copy_channel_in_float, pcm, frame_size, data,
+    max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st));
+}
+#else
+int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
+                                 int frame_size, unsigned char *data,
+                                 opus_int32 max_data_bytes)
+{
+  return opus_multistream_encode_native(get_multistream_encoder(st),
+    opus_projection_copy_channel_in_float, pcm, frame_size, data,
+    max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st));
+}
+#endif
+#endif
+
+void opus_projection_encoder_destroy(OpusProjectionEncoder *st)
+{
+  opus_free(st);
+}
+
+int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...)
+{
+  va_list ap;
+  MappingMatrix *demixing_matrix;
+  OpusMSEncoder *ms_encoder;
+  int ret = OPUS_OK;
+
+  ms_encoder = get_multistream_encoder(st);
+  demixing_matrix = get_enc_demixing_matrix(st);
+
+  va_start(ap, request);
+  switch(request)
+  {
+  case OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST:
+  {
+    opus_int32 *value = va_arg(ap, opus_int32*);
+    if (!value)
+    {
+      goto bad_arg;
+    }
+    *value =
+      ms_encoder->layout.nb_channels * (ms_encoder->layout.nb_streams
+      + ms_encoder->layout.nb_coupled_streams) * sizeof(opus_int16);
+  }
+  break;
+  case OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST:
+  {
+    opus_int32 *value = va_arg(ap, opus_int32*);
+    if (!value)
+    {
+      goto bad_arg;
+    }
+    *value = demixing_matrix->gain;
+  }
+  break;
+  case OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST:
+  {
+    int i, j, k, l;
+    int nb_input_streams;
+    int nb_output_streams;
+    unsigned char *external_char;
+    opus_int16 *internal_short;
+    opus_int32 external_size;
+    opus_int32 internal_size;
+
+    /* (I/O is in relation to the decoder's perspective). */
+    nb_input_streams = ms_encoder->layout.nb_streams +
+      ms_encoder->layout.nb_coupled_streams;
+    nb_output_streams = ms_encoder->layout.nb_channels;
+
+    external_char = va_arg(ap, unsigned char *);
+    external_size = va_arg(ap, opus_int32);
+    if (!external_char)
+    {
+      goto bad_arg;
+    }
+    internal_short = mapping_matrix_get_data(demixing_matrix);
+    internal_size = nb_input_streams * nb_output_streams * sizeof(opus_int16);
+    if (external_size != internal_size)
+    {
+      goto bad_arg;
+    }
+
+    /* Copy demixing matrix subset to output destination. */
+    l = 0;
+    for (i = 0; i < nb_input_streams; i++) {
+      for (j = 0; j < nb_output_streams; j++) {
+        k = demixing_matrix->rows * i + j;
+        external_char[2*l] = (unsigned char)internal_short[k];
+        external_char[2*l+1] = (unsigned char)(internal_short[k] >> 8);
+        l++;
+      }
+    }
+  }
+  break;
+  default:
+  {
+    ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap);
+  }
+  break;
+  }
+  va_end(ap);
+  return ret;
+
+bad_arg:
+  va_end(ap);
+  return OPUS_BAD_ARG;
+}
+
diff --git a/src/repacketizer.c b/src/repacketizer.c
index c80ee7f..bda44a1 100644
--- a/src/repacketizer.c
+++ b/src/repacketizer.c
@@ -213,7 +213,8 @@
    {
       /* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place
          padding from opus_packet_pad or opus_packet_unpad(). */
-      celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]);
+      /* assert disabled because it's not valid in C. */
+      /* celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]); */
       OPUS_MOVE(ptr, frames[i], len[i]);
       ptr += len[i];
    }
diff --git a/tests/opus_decode_fuzzer.c b/tests/opus_decode_fuzzer.c
index 4b4a3f3..9002622 100644
--- a/tests/opus_decode_fuzzer.c
+++ b/tests/opus_decode_fuzzer.c
@@ -28,6 +28,7 @@
 #include "config.h"
 #endif
 
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include "opus.h"
diff --git a/tests/test_opus_api.c b/tests/test_opus_api.c
index 1d00950..fb385c6 100644
--- a/tests/test_opus_api.c
+++ b/tests/test_opus_api.c
@@ -78,6 +78,9 @@
 }
 #endif
 
+opus_int32 *null_int_ptr = (opus_int32 *)NULL;
+opus_uint32 *null_uint_ptr = (opus_uint32 *)NULL;
+
 static const opus_int32 opus_rates[5] = {48000,24000,16000,12000,8000};
 
 opus_int32 test_dec_api(void)
@@ -92,8 +95,6 @@
 #endif
    short sbuf[960*2];
    int c,err;
-   opus_int32 *nullvalue;
-   nullvalue=0;
 
    cfgs=0;
    /*First test invalid configurations which should fail*/
@@ -147,7 +148,7 @@
    fprintf(stdout,"    opus_decoder_create() ........................ OK.\n");
    fprintf(stdout,"    opus_decoder_init() .......................... OK.\n");
 
-   err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE((opus_uint32 *)NULL));
+   err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(null_uint_ptr));
    if(err != OPUS_BAD_ARG)test_failed();
    VG_UNDEF(&dec_final_range,sizeof(dec_final_range));
    err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
@@ -161,7 +162,7 @@
    fprintf(stdout,"    OPUS_UNIMPLEMENTED ........................... OK.\n");
    cfgs++;
 
-   err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH((opus_int32 *)NULL));
+   err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(null_int_ptr));
    if(err != OPUS_BAD_ARG)test_failed();
    VG_UNDEF(&i,sizeof(i));
    err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i));
@@ -169,7 +170,7 @@
    fprintf(stdout,"    OPUS_GET_BANDWIDTH ........................... OK.\n");
    cfgs++;
 
-   err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE((opus_int32 *)NULL));
+   err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(null_int_ptr));
    if(err != OPUS_BAD_ARG)test_failed();
    VG_UNDEF(&i,sizeof(i));
    err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(&i));
@@ -178,7 +179,7 @@
    cfgs++;
 
    /*GET_PITCH has different execution paths depending on the previously decoded frame.*/
-   err=opus_decoder_ctl(dec, OPUS_GET_PITCH(nullvalue));
+   err=opus_decoder_ctl(dec, OPUS_GET_PITCH(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    VG_UNDEF(&i,sizeof(i));
@@ -202,7 +203,7 @@
    cfgs++;
    fprintf(stdout,"    OPUS_GET_PITCH ............................... OK.\n");
 
-   err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION((opus_int32 *)NULL));
+   err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(null_int_ptr));
    if(err != OPUS_BAD_ARG)test_failed();
    VG_UNDEF(&i,sizeof(i));
    err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&i));
@@ -215,7 +216,7 @@
    VG_CHECK(&i,sizeof(i));
    if(err != OPUS_OK || i!=0)test_failed();
    cfgs++;
-   err=opus_decoder_ctl(dec, OPUS_GET_GAIN(nullvalue));
+   err=opus_decoder_ctl(dec, OPUS_GET_GAIN(null_int_ptr));
    if(err != OPUS_BAD_ARG)test_failed();
    cfgs++;
    err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-32769));
@@ -352,11 +353,6 @@
 #endif
    short sbuf[960*2];
    int a,b,c,err;
-#if 0
-   /*Relevant test not enabled for multistream*/
-   int *nullvalue;
-   nullvalue=0;
-#endif
 
    mapping[0]=0;
    mapping[1]=1;
@@ -610,7 +606,7 @@
 #if 0
    /*Currently unimplemented for multistream*/
    /*GET_PITCH has different execution paths depending on the previously decoded frame.*/
-   err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(nullvalue));
+   err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    VG_UNDEF(&i,sizeof(i));
@@ -657,6 +653,8 @@
    packet[1]=packet[2]=0;
    if(opus_multistream_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG){printf("%d\n",opus_multistream_decode(dec, packet, -1, sbuf, 960, 0));test_failed();}
    cfgs++;
+   if(opus_multistream_decode(dec, packet, 3, sbuf, -960, 0)!=OPUS_BAD_ARG)test_failed();
+   cfgs++;
    if(opus_multistream_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed();
    cfgs++;
    if(opus_multistream_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed();
@@ -1166,7 +1164,7 @@
    err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i));
    if(err!=OPUS_OK || i<0 || i>32766)test_failed();
    cfgs++;
-   err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    fprintf(stdout,"    OPUS_GET_LOOKAHEAD ........................... OK.\n");
@@ -1174,7 +1172,7 @@
    err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(&i));
    if(err!=OPUS_OK || i!=48000)test_failed();
    cfgs++;
-   err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    fprintf(stdout,"    OPUS_GET_SAMPLE_RATE ......................... OK.\n");
@@ -1183,7 +1181,7 @@
    fprintf(stdout,"    OPUS_UNIMPLEMENTED ........................... OK.\n");
    cfgs++;
 
-   err=opus_encoder_ctl(enc,OPUS_GET_APPLICATION((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_APPLICATION(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_APPLICATION(i),OPUS_GET_APPLICATION(&i),-1,OPUS_AUTO,
@@ -1191,7 +1189,7 @@
      "    OPUS_SET_APPLICATION ......................... OK.\n",
      "    OPUS_GET_APPLICATION ......................... OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_BITRATE((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_BITRATE(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    if(opus_encoder_ctl(enc,OPUS_SET_BITRATE(1073741832))!=OPUS_OK)test_failed();
@@ -1205,7 +1203,7 @@
      "    OPUS_SET_BITRATE ............................. OK.\n",
      "    OPUS_GET_BITRATE ............................. OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_FORCE_CHANNELS((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_FORCE_CHANNELS(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_FORCE_CHANNELS(i),OPUS_GET_FORCE_CHANNELS(&i),-1,3,
@@ -1243,7 +1241,7 @@
    cfgs++;
    if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed();
    cfgs++;
-   err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    fprintf(stdout,"    OPUS_GET_BANDWIDTH ........................... OK.\n");
@@ -1276,12 +1274,12 @@
       i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&&
       i!=OPUS_BANDWIDTH_FULLBAND))test_failed();
    cfgs++;
-   err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    fprintf(stdout,"    OPUS_GET_MAX_BANDWIDTH ....................... OK.\n");
 
-   err=opus_encoder_ctl(enc,OPUS_GET_DTX((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_DTX(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_DTX(i),OPUS_GET_DTX(&i),-1,2,
@@ -1289,7 +1287,7 @@
      "    OPUS_SET_DTX ................................. OK.\n",
      "    OPUS_GET_DTX ................................. OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_COMPLEXITY((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_COMPLEXITY(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_COMPLEXITY(i),OPUS_GET_COMPLEXITY(&i),-1,11,
@@ -1297,7 +1295,7 @@
      "    OPUS_SET_COMPLEXITY .......................... OK.\n",
      "    OPUS_GET_COMPLEXITY .......................... OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_INBAND_FEC((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_INBAND_FEC(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_INBAND_FEC(i),OPUS_GET_INBAND_FEC(&i),-1,2,
@@ -1305,7 +1303,7 @@
      "    OPUS_SET_INBAND_FEC .......................... OK.\n",
      "    OPUS_GET_INBAND_FEC .......................... OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_PACKET_LOSS_PERC((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_PACKET_LOSS_PERC(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_PACKET_LOSS_PERC(i),OPUS_GET_PACKET_LOSS_PERC(&i),-1,101,
@@ -1313,7 +1311,7 @@
      "    OPUS_SET_PACKET_LOSS_PERC .................... OK.\n",
      "    OPUS_GET_PACKET_LOSS_PERC .................... OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_VBR((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_VBR(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_VBR(i),OPUS_GET_VBR(&i),-1,2,
@@ -1321,7 +1319,7 @@
      "    OPUS_SET_VBR ................................. OK.\n",
      "    OPUS_GET_VBR ................................. OK.\n")
 
-/*   err=opus_encoder_ctl(enc,OPUS_GET_VOICE_RATIO((opus_int32 *)NULL));
+/*   err=opus_encoder_ctl(enc,OPUS_GET_VOICE_RATIO(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_VOICE_RATIO(i),OPUS_GET_VOICE_RATIO(&i),-2,101,
@@ -1329,7 +1327,7 @@
      "    OPUS_SET_VOICE_RATIO ......................... OK.\n",
      "    OPUS_GET_VOICE_RATIO ......................... OK.\n")*/
 
-   err=opus_encoder_ctl(enc,OPUS_GET_VBR_CONSTRAINT((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_VBR_CONSTRAINT(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_VBR_CONSTRAINT(i),OPUS_GET_VBR_CONSTRAINT(&i),-1,2,
@@ -1337,7 +1335,7 @@
      "    OPUS_SET_VBR_CONSTRAINT ...................... OK.\n",
      "    OPUS_GET_VBR_CONSTRAINT ...................... OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_SIGNAL((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_SIGNAL(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_SIGNAL(i),OPUS_GET_SIGNAL(&i),-12345,0x7FFFFFFF,
@@ -1345,7 +1343,7 @@
      "    OPUS_SET_SIGNAL .............................. OK.\n",
      "    OPUS_GET_SIGNAL .............................. OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_LSB_DEPTH((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_LSB_DEPTH(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_LSB_DEPTH(i),OPUS_GET_LSB_DEPTH(&i),7,25,16,24,
@@ -1355,14 +1353,14 @@
    err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(&i));
    if(i!=0)test_failed();
    cfgs++;
-   err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    CHECK_SETGET(OPUS_SET_PREDICTION_DISABLED(i),OPUS_GET_PREDICTION_DISABLED(&i),-1,2,1,0,
      "    OPUS_SET_PREDICTION_DISABLED ................. OK.\n",
      "    OPUS_GET_PREDICTION_DISABLED ................. OK.\n")
 
-   err=opus_encoder_ctl(enc,OPUS_GET_EXPERT_FRAME_DURATION((opus_int32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_EXPERT_FRAME_DURATION(null_int_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_2_5_MS));
@@ -1399,7 +1397,7 @@
 
    /*OPUS_SET_FORCE_MODE is not tested here because it's not a public API, however the encoder tests use it*/
 
-   err=opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE((opus_uint32 *)NULL));
+   err=opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(null_uint_ptr));
    if(err!=OPUS_BAD_ARG)test_failed();
    cfgs++;
    if(opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();
diff --git a/tests/test_opus_common.h b/tests/test_opus_common.h
index ff7f014..235cf1c 100644
--- a/tests/test_opus_common.h
+++ b/tests/test_opus_common.h
@@ -64,6 +64,8 @@
 
 #ifdef __GNUC__
 __attribute__((noreturn))
+#elif defined(_MSC_VER)
+__declspec(noreturn)
 #endif
 static OPUS_INLINE void _test_failed(const char *file, int line)
 {
diff --git a/tests/test_opus_projection.c b/tests/test_opus_projection.c
new file mode 100644
index 0000000..4d622e8
--- /dev/null
+++ b/tests/test_opus_projection.c
@@ -0,0 +1,392 @@
+/* Copyright (c) 2017 Google Inc.
+   Written by Andrew Allen */
+/*
+   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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "float_cast.h"
+#include "opus.h"
+#include "test_opus_common.h"
+#include "opus_projection.h"
+#include "mathops.h"
+#include "../src/mapping_matrix.h"
+#include "mathops.h"
+
+#define BUFFER_SIZE 960
+#define MAX_DATA_BYTES 32768
+#define MAX_FRAME_SAMPLES 5760
+#define ERROR_TOLERANCE 1
+
+#define SIMPLE_MATRIX_SIZE 12
+#define SIMPLE_MATRIX_FRAME_SIZE 10
+#define SIMPLE_MATRIX_INPUT_SIZE 30
+#define SIMPLE_MATRIX_OUTPUT_SIZE 40
+
+int assert_is_equal(
+  const opus_val16 *a, const opus_int16 *b, int size, opus_int16 tolerance)
+{
+  int i;
+  for (i = 0; i < size; i++)
+  {
+#ifdef FIXED_POINT
+    opus_int16 val = a[i];
+#else
+    opus_int16 val = FLOAT2INT16(a[i]);
+#endif
+    if (abs(val - b[i]) > tolerance)
+      return 1;
+  }
+  return 0;
+}
+
+int assert_is_equal_short(
+  const opus_int16 *a, const opus_int16 *b, int size, opus_int16 tolerance)
+{
+  int i;
+  for (i = 0; i < size; i++)
+    if (abs(a[i] - b[i]) > tolerance)
+      return 1;
+  return 0;
+}
+
+void test_simple_matrix(void)
+{
+  const MappingMatrix simple_matrix_params = {4, 3, 0};
+  const opus_int16 simple_matrix_data[SIMPLE_MATRIX_SIZE] = {0, 32767, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 32767};
+  const opus_int16 input_int16[SIMPLE_MATRIX_INPUT_SIZE] = {
+    32767, 0, -32768, 29491, -3277, -29491, 26214, -6554, -26214, 22938, -9830,
+    -22938, 19661, -13107, -19661, 16384, -16384, -16384, 13107, -19661, -13107,
+    9830, -22938, -9830, 6554, -26214, -6554, 3277, -29491, -3277};
+  const opus_int16 expected_output_int16[SIMPLE_MATRIX_OUTPUT_SIZE] = {
+    0, 32767, 0, -32768, -3277, 29491, 0, -29491, -6554, 26214, 0, -26214,
+    -9830, 22938, 0, -22938, -13107, 19661, 0, -19661, -16384, 16384, 0, -16384,
+    -19661, 13107, 0, -13107, -22938, 9830, 0, -9830, -26214, 6554, 0, -6554,
+    -29491, 3277, 0, -3277};
+
+  int i, ret;
+  opus_int32 simple_matrix_size;
+  opus_val16 *input_val16;
+  opus_val16 *output_val16;
+  opus_int16 *output_int16;
+  MappingMatrix *simple_matrix;
+
+  /* Allocate input/output buffers. */
+  input_val16 = (opus_val16 *)opus_alloc(sizeof(opus_val16) * SIMPLE_MATRIX_INPUT_SIZE);
+  output_int16 = (opus_int16 *)opus_alloc(sizeof(opus_int16) * SIMPLE_MATRIX_OUTPUT_SIZE);
+  output_val16 = (opus_val16 *)opus_alloc(sizeof(opus_val16) * SIMPLE_MATRIX_OUTPUT_SIZE);
+
+  /* Initialize matrix */
+  simple_matrix_size = mapping_matrix_get_size(simple_matrix_params.rows,
+    simple_matrix_params.cols);
+  if (!simple_matrix_size)
+    test_failed();
+
+  simple_matrix = (MappingMatrix *)opus_alloc(simple_matrix_size);
+  mapping_matrix_init(simple_matrix, simple_matrix_params.rows,
+    simple_matrix_params.cols, simple_matrix_params.gain, simple_matrix_data,
+    sizeof(simple_matrix_data));
+
+  /* Copy inputs. */
+  for (i = 0; i < SIMPLE_MATRIX_INPUT_SIZE; i++)
+  {
+#ifdef FIXED_POINT
+    input_val16[i] = input_int16[i];
+#else
+    input_val16[i] = (1/32768.f)*input_int16[i];
+#endif
+  }
+
+  /* _in_short */
+  for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
+    output_val16[i] = 0;
+  for (i = 0; i < simple_matrix->rows; i++)
+  {
+    mapping_matrix_multiply_channel_in_short(simple_matrix,
+      input_int16, simple_matrix->cols, &output_val16[i], i,
+      simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
+  }
+  ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
+  if (ret)
+    test_failed();
+
+  /* _out_short */
+  for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
+    output_int16[i] = 0;
+  for (i = 0; i < simple_matrix->cols; i++)
+  {
+    mapping_matrix_multiply_channel_out_short(simple_matrix,
+      &input_val16[i], i, simple_matrix->cols, output_int16,
+      simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
+  }
+  ret = assert_is_equal_short(output_int16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
+  if (ret)
+    test_failed();
+
+#if !defined(DISABLE_FLOAT_API) && !defined(FIXED_POINT)
+  /* _in_float */
+  for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
+    output_val16[i] = 0;
+  for (i = 0; i < simple_matrix->rows; i++)
+  {
+    mapping_matrix_multiply_channel_in_float(simple_matrix,
+      input_val16, simple_matrix->cols, &output_val16[i], i,
+      simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
+  }
+  ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
+  if (ret)
+    test_failed();
+
+  /* _out_float */
+  for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
+    output_val16[i] = 0;
+  for (i = 0; i < simple_matrix->cols; i++)
+  {
+    mapping_matrix_multiply_channel_out_float(simple_matrix,
+      &input_val16[i], i, simple_matrix->cols, output_val16,
+      simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
+  }
+  ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
+  if (ret)
+    test_failed();
+#endif
+
+  opus_free(input_val16);
+  opus_free(output_int16);
+  opus_free(output_val16);
+  opus_free(simple_matrix);
+}
+
+void test_creation_arguments(const int channels, const int mapping_family)
+{
+  int streams;
+  int coupled_streams;
+  int enc_error;
+  int dec_error;
+  int ret;
+  OpusProjectionEncoder *st_enc = NULL;
+  OpusProjectionDecoder *st_dec = NULL;
+
+  const opus_int32 Fs = 48000;
+  const int application = OPUS_APPLICATION_AUDIO;
+
+  int order_plus_one = (int)floor(sqrt((float)channels));
+  int nondiegetic_channels = channels - order_plus_one * order_plus_one;
+
+  int is_channels_valid = 0;
+  int is_projection_valid = 0;
+
+  st_enc = opus_projection_ambisonics_encoder_create(Fs, channels,
+    mapping_family, &streams, &coupled_streams, application, &enc_error);
+  if (st_enc != NULL)
+  {
+    opus_int32 matrix_size;
+    unsigned char *matrix;
+
+    ret = opus_projection_encoder_ctl(st_enc,
+      OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, &matrix_size);
+    if (ret != OPUS_OK || !matrix_size)
+      test_failed();
+
+    matrix = (unsigned char *)opus_alloc(matrix_size);
+    ret = opus_projection_encoder_ctl(st_enc,
+      OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, matrix, matrix_size);
+
+    opus_projection_encoder_destroy(st_enc);
+
+    st_dec = opus_projection_decoder_create(Fs, channels, streams,
+      coupled_streams, matrix, matrix_size, &dec_error);
+    if (st_dec != NULL)
+    {
+      opus_projection_decoder_destroy(st_dec);
+    }
+    opus_free(matrix);
+  }
+
+  is_channels_valid = (order_plus_one >= 2 && order_plus_one <= 4) &&
+    (nondiegetic_channels == 0 || nondiegetic_channels == 2);
+  is_projection_valid = (enc_error == OPUS_OK && dec_error == OPUS_OK);
+  if (is_channels_valid ^ is_projection_valid)
+  {
+    fprintf(stderr, "Channels: %d, Family: %d\n", channels, mapping_family);
+    fprintf(stderr, "Order+1: %d, Non-diegetic Channels: %d\n",
+      order_plus_one, nondiegetic_channels);
+    fprintf(stderr, "Streams: %d, Coupled Streams: %d\n",
+      streams, coupled_streams);
+    test_failed();
+  }
+}
+
+void generate_music(short *buf, opus_int32 len, opus_int32 channels)
+{
+   opus_int32 i,j,k;
+   opus_int32 *a,*b,*c,*d;
+   a = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
+   b = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
+   c = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
+   d = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
+   memset(a, 0, sizeof(opus_int32) * channels);
+   memset(b, 0, sizeof(opus_int32) * channels);
+   memset(c, 0, sizeof(opus_int32) * channels);
+   memset(d, 0, sizeof(opus_int32) * channels);
+   j=0;
+
+   for(i=0;i<len;i++)
+   {
+     for(k=0;k<channels;k++)
+     {
+      opus_uint32 r;
+      opus_int32 v;
+      v=(((j*((j>>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15;
+      r=fast_rand();v+=r&65535;v-=r>>16;
+      b[k]=v-a[k]+((b[k]*61+32)>>6);a[k]=v;
+      c[k]=(30*(c[k]+b[k]+d[k])+32)>>6;d[k]=b[k];
+      v=(c[k]+128)>>8;
+      buf[i*channels+k]=v>32767?32767:(v<-32768?-32768:v);
+      if(i%6==0)j++;
+     }
+   }
+
+   free(a);
+   free(b);
+   free(c);
+   free(d);
+}
+
+void test_encode_decode(opus_int32 bitrate, opus_int32 channels,
+                        const int mapping_family)
+{
+  const opus_int32 Fs = 48000;
+  const int application = OPUS_APPLICATION_AUDIO;
+
+  OpusProjectionEncoder *st_enc;
+  OpusProjectionDecoder *st_dec;
+  int streams;
+  int coupled;
+  int error;
+  short *buffer_in;
+  short *buffer_out;
+  unsigned char data[MAX_DATA_BYTES] = { 0 };
+  int len;
+  int out_samples;
+  opus_int32 matrix_size = 0;
+  unsigned char *matrix = NULL;
+
+  buffer_in = (short *)malloc(sizeof(short) * BUFFER_SIZE * channels);
+  buffer_out = (short *)malloc(sizeof(short) * BUFFER_SIZE * channels);
+
+  st_enc = opus_projection_ambisonics_encoder_create(Fs, channels,
+    mapping_family, &streams, &coupled, application, &error);
+  if (error != OPUS_OK) {
+    fprintf(stderr,
+      "Couldn\'t create encoder with %d channels and mapping family %d.\n",
+      channels, mapping_family);
+    free(buffer_in);
+    free(buffer_out);
+    test_failed();
+  }
+
+  error = opus_projection_encoder_ctl(st_enc,
+    OPUS_SET_BITRATE(bitrate * 1000 * (streams + coupled)));
+  if (error != OPUS_OK)
+  {
+    goto bad_cleanup;
+  }
+
+  error = opus_projection_encoder_ctl(st_enc,
+    OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, &matrix_size);
+  if (error != OPUS_OK || !matrix_size)
+  {
+    goto bad_cleanup;
+  }
+
+  matrix = (unsigned char *)opus_alloc(matrix_size);
+  error = opus_projection_encoder_ctl(st_enc,
+    OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, matrix, matrix_size);
+
+  st_dec = opus_projection_decoder_create(Fs, channels, streams, coupled,
+    matrix, matrix_size, &error);
+  opus_free(matrix);
+
+  if (error != OPUS_OK) {
+    fprintf(stderr,
+      "Couldn\'t create decoder with %d channels, %d streams "
+      "and %d coupled streams.\n", channels, streams, coupled);
+    goto bad_cleanup;
+  }
+
+  generate_music(buffer_in, BUFFER_SIZE, channels);
+
+  len = opus_projection_encode(
+    st_enc, buffer_in, BUFFER_SIZE, data, MAX_DATA_BYTES);
+  if(len<0 || len>MAX_DATA_BYTES) {
+    fprintf(stderr,"opus_encode() returned %d\n", len);
+    goto bad_cleanup;
+  }
+
+  out_samples = opus_projection_decode(
+    st_dec, data, len, buffer_out, MAX_FRAME_SAMPLES, 0);
+  if(out_samples!=BUFFER_SIZE) {
+    fprintf(stderr,"opus_decode() returned %d\n", out_samples);
+    goto bad_cleanup;
+  }
+
+  free(buffer_in);
+  free(buffer_out);
+  return;
+bad_cleanup:
+  free(buffer_in);
+  free(buffer_out);
+  test_failed();
+}
+
+int main(int _argc, char **_argv)
+{
+  unsigned int i;
+
+  (void)_argc;
+  (void)_argv;
+
+  /* Test simple matrix multiplication routines. */
+  test_simple_matrix();
+
+  /* Test full range of channels in creation arguments. */
+  for (i = 0; i < 255; i++)
+    test_creation_arguments(i, 3);
+
+  /* Test encode/decode pipeline. */
+  test_encode_decode(64 * 18, 18, 3);
+
+  fprintf(stderr, "All projection tests passed.\n");
+  return 0;
+}
+
diff --git a/win32/VS2015/common.props b/win32/VS2015/common.props
index 6c757d8..03cd45b 100644
--- a/win32/VS2015/common.props
+++ b/win32/VS2015/common.props
@@ -1,82 +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 />
+<?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 7b678e7..abd7a4d 100644
--- a/win32/VS2015/opus.sln
+++ b/win32/VS2015/opus.sln
@@ -1,168 +1,168 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "opus.vcxproj", "{219EC965-228A-1824-174D-96449D05F88A}"
-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}
-	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}
-	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}
-	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}
-	EndProjectSection
-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
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.ActiveCfg = Debug|Win32
-		{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
-		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.ActiveCfg = Release|Win32
-		{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
-		{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
-		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.ActiveCfg = Release|Win32
-		{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
-		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.ActiveCfg = Debug|Win32
-		{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
-		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.ActiveCfg = Release|Win32
-		{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
-		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.ActiveCfg = Debug|Win32
-		{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
-		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.ActiveCfg = Release|Win32
-		{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
-		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64
-		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.ActiveCfg = Debug|Win32
-		{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
-		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|x64.Build.0 = DebugDLL|x64
-		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.ActiveCfg = Release|Win32
-		{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
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+

+Microsoft Visual Studio Solution File, Format Version 12.00

+# Visual Studio 14

+VisualStudioVersion = 14.0.25420.1

+MinimumVisualStudioVersion = 10.0.40219.1

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "opus.vcxproj", "{219EC965-228A-1824-174D-96449D05F88A}"

+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}

+	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}

+	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}

+	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}

+	EndProjectSection

+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

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{219EC965-228A-1824-174D-96449D05F88A}.Debug|Win32.ActiveCfg = Debug|Win32

+		{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

+		{219EC965-228A-1824-174D-96449D05F88A}.DebugDLL|x64.Build.0 = DebugDLL|x64

+		{219EC965-228A-1824-174D-96449D05F88A}.Release|Win32.ActiveCfg = Release|Win32

+		{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

+		{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

+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.DebugDLL|x64.Build.0 = DebugDLL|x64

+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.Release|Win32.ActiveCfg = Release|Win32

+		{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

+		{016C739D-6389-43BF-8D88-24B2BF6F620F}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64

+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Debug|Win32.ActiveCfg = Debug|Win32

+		{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

+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.DebugDLL|x64.Build.0 = DebugDLL|x64

+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.Release|Win32.ActiveCfg = Release|Win32

+		{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

+		{1D257A17-D254-42E5-82D6-1C87A6EC775A}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64

+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Debug|Win32.ActiveCfg = Debug|Win32

+		{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

+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.DebugDLL|x64.Build.0 = DebugDLL|x64

+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.Release|Win32.ActiveCfg = Release|Win32

+		{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

+		{8578322A-1883-486B-B6FA-E0094B65C9F2}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64

+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Debug|Win32.ActiveCfg = Debug|Win32

+		{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

+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.DebugDLL|x64.Build.0 = DebugDLL|x64

+		{84DAA768-1A38-4312-BB61-4C78BB59E5B8}.Release|Win32.ActiveCfg = Release|Win32

+		{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

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/win32/VS2015/opus.vcxproj b/win32/VS2015/opus.vcxproj
index 33bf706..e7a17da 100644
--- a/win32/VS2015/opus.vcxproj
+++ b/win32/VS2015/opus.vcxproj
@@ -1,394 +1,399 @@
-<?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>
-    </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_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>
-    </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">
-    <Keyword>Win32Proj</Keyword>
-    <ProjectName>opus</ProjectName>
-    <ProjectGuid>{219EC965-228A-1824-174D-96449D05F88A}</ProjectGuid>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <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">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </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" />
-  <ItemDefinitionGroup>
-    <ClCompile>
-      <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>
-    <Lib>
-      <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>
-    </Lib>
-    <PreBuildEvent>
-      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>
-      <Message>Generating version.h</Message>
-    </PreBuildEvent>
-  </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" />
-    <ClInclude Include="..\..\src\opus_private.h" />
-    <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">
-      <DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
-    </ClCompile>
-    <ClCompile Include="..\..\src\opus_decoder.c" />
-    <ClCompile Include="..\..\src\opus_encoder.c" />
-    <ClCompile Include="..\..\src\opus_multistream.c" />
-    <ClCompile Include="..\..\src\opus_multistream_decoder.c" />
-    <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>
-</Project>
\ No newline at end of file
+<?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>

+    </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_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>

+    </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">

+    <Keyword>Win32Proj</Keyword>

+    <ProjectName>opus</ProjectName>

+    <ProjectGuid>{219EC965-228A-1824-174D-96449D05F88A}</ProjectGuid>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>StaticLibrary</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">

+    <ConfigurationType>DynamicLibrary</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">

+    <ConfigurationType>DynamicLibrary</ConfigurationType>

+    <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">

+    <ConfigurationType>StaticLibrary</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">

+    <ConfigurationType>DynamicLibrary</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">

+    <ConfigurationType>DynamicLibrary</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </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" />

+  <ItemDefinitionGroup>

+    <ClCompile>

+      <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>

+    <Lib>

+      <AdditionalOptions>/ignore:4221 %(AdditionalOptions)</AdditionalOptions>

+    </Lib>

+    <PreBuildEvent>

+      <Command>"$(ProjectDir)..\..\win32\genversion.bat" "$(ProjectDir)..\..\win32\version.h" PACKAGE_VERSION</Command>

+      <Message>Generating version.h</Message>

+    </PreBuildEvent>

+  </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="..\..\include\opus_projection.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\mapping_matrix.h" />

+    <ClInclude Include="..\..\src\mlp.h" />

+    <ClInclude Include="..\..\src\opus_private.h" />

+    <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_sse4_1.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_sse4_1.c" />

+    <ClCompile Include="..\..\silk\x86\NSQ_sse4_1.c" />

+    <ClCompile Include="..\..\silk\x86\VAD_sse4_1.c" />

+    <ClCompile Include="..\..\silk\x86\VQ_WMat_EC_sse4_1.c" />

+    <ClCompile Include="..\..\silk\x86\x86_silk_map.c" />

+    <ClCompile Include="..\..\src\analysis.c" />

+    <ClCompile Include="..\..\src\mapping_matrix.c" />

+    <ClCompile Include="..\..\src\mlp.c" />

+    <ClCompile Include="..\..\src\mlp_data.c" />

+    <ClCompile Include="..\..\src\opus.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" />

+    <ClCompile Include="..\..\src\opus_multistream_decoder.c" />

+    <ClCompile Include="..\..\src\opus_multistream_encoder.c" />

+    <ClCompile Include="..\..\src\opus_projection_decoder.c" />

+    <ClCompile Include="..\..\src\opus_projection_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>

+</Project>

diff --git a/win32/VS2015/opus.vcxproj.filters b/win32/VS2015/opus.vcxproj.filters
index bb82b64..d59c756 100644
--- a/win32/VS2015/opus.vcxproj.filters
+++ b/win32/VS2015/opus.vcxproj.filters
@@ -1,570 +1,585 @@
-<?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</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\celt\arch.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\celt.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\float_cast.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\os_support.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\celt\stack_alloc.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\opus.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\opus_defines.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\opus_types.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\include\opus_multistream.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\win32\config.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\analysis.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\mlp.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\opus_private.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <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>
-    <ClCompile Include="..\..\src\opus_compare.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\opus_decoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\opus_encoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\opus_multistream.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\opus_multistream_decoder.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <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="..\..\celt\vq.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>
-    <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>
\ No newline at end of file
+<?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</Extensions>

+    </Filter>

+  </ItemGroup>

+  <ItemGroup>

+    <ClInclude Include="..\..\celt\arch.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\celt\celt.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\float_cast.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\celt\os_support.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\celt\stack_alloc.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\include\opus.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\include\opus_defines.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\include\opus_types.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\include\opus_multistream.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\include\opus_projection.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\win32\config.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\src\analysis.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\src\mapping_matrix.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\src\mlp.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="..\..\src\opus_private.h">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <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_sse4_1.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="..\..\src\mapping_matrix.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>

+    <ClCompile Include="..\..\src\opus_compare.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_decoder.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_encoder.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_multistream.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_multistream_decoder.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_multistream_encoder.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_projection_decoder.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\src\opus_projection_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="..\..\celt\vq.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>

+    <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_sse4_1.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+    <ClCompile Include="..\..\silk\x86\NSQ_sse4_1.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_sse4_1.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_sse4_1.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>

diff --git a/win32/VS2015/opus_demo.vcxproj b/win32/VS2015/opus_demo.vcxproj
index f4344e5..9860bf9 100644
--- a/win32/VS2015/opus_demo.vcxproj
+++ b/win32/VS2015/opus_demo.vcxproj
@@ -1,171 +1,171 @@
-<?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>
-    </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_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>
-    </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>
-    <ProjectReference Include="opus.vcxproj">
-      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\src\opus_demo.c" />
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{016C739D-6389-43BF-8D88-24B2BF6F620F}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>opus_demo</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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" />
-  <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" />
-  <ItemDefinitionGroup />
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?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>

+    </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_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>

+    </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>

+    <ProjectReference Include="opus.vcxproj">

+      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>

+    </ProjectReference>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\src\opus_demo.c" />

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{016C739D-6389-43BF-8D88-24B2BF6F620F}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>opus_demo</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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" />

+  <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" />

+  <ItemDefinitionGroup />

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

 </Project>
\ No newline at end of file
diff --git a/win32/VS2015/opus_demo.vcxproj.filters b/win32/VS2015/opus_demo.vcxproj.filters
index 2eb113a..dbcc8ae 100644
--- a/win32/VS2015/opus_demo.vcxproj.filters
+++ b/win32/VS2015/opus_demo.vcxproj.filters
@@ -1,22 +1,22 @@
-<?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="..\..\src\opus_demo.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
+<?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="..\..\src\opus_demo.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 7cae131..c6abf88 100644
--- a/win32/VS2015/test_opus_api.vcxproj
+++ b/win32/VS2015/test_opus_api.vcxproj
@@ -1,171 +1,171 @@
-<?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>
-    </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_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>
-    </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="..\..\tests\test_opus_api.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="opus.vcxproj">
-      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{1D257A17-D254-42E5-82D6-1C87A6EC775A}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>test_opus_api</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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" />
-  <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" />
-  <ItemDefinitionGroup />
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?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>

+    </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_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>

+    </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="..\..\tests\test_opus_api.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="opus.vcxproj">

+      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>

+    </ProjectReference>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{1D257A17-D254-42E5-82D6-1C87A6EC775A}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>test_opus_api</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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" />

+  <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" />

+  <ItemDefinitionGroup />

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

 </Project>
\ No newline at end of file
diff --git a/win32/VS2015/test_opus_api.vcxproj.filters b/win32/VS2015/test_opus_api.vcxproj.filters
index 383d19f..070c8ab 100644
--- a/win32/VS2015/test_opus_api.vcxproj.filters
+++ b/win32/VS2015/test_opus_api.vcxproj.filters
@@ -1,14 +1,14 @@
-<?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>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\tests\test_opus_api.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
+<?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>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\tests\test_opus_api.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+  </ItemGroup>

 </Project>
\ No newline at end of file
diff --git a/win32/VS2015/test_opus_decode.vcxproj b/win32/VS2015/test_opus_decode.vcxproj
index df01dca..9db09b8 100644
--- a/win32/VS2015/test_opus_decode.vcxproj
+++ b/win32/VS2015/test_opus_decode.vcxproj
@@ -1,171 +1,171 @@
-<?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>
-    </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_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>
-    </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="..\..\tests\test_opus_decode.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="opus.vcxproj">
-      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{8578322A-1883-486B-B6FA-E0094B65C9F2}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>test_opus_api</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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" />
-  <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" />
-  <ItemDefinitionGroup />
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?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>

+    </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_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>

+    </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="..\..\tests\test_opus_decode.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="opus.vcxproj">

+      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>

+    </ProjectReference>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{8578322A-1883-486B-B6FA-E0094B65C9F2}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>test_opus_api</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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" />

+  <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" />

+  <ItemDefinitionGroup />

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

 </Project>
\ No newline at end of file
diff --git a/win32/VS2015/test_opus_decode.vcxproj.filters b/win32/VS2015/test_opus_decode.vcxproj.filters
index 3036a4e..588637e 100644
--- a/win32/VS2015/test_opus_decode.vcxproj.filters
+++ b/win32/VS2015/test_opus_decode.vcxproj.filters
@@ -1,14 +1,14 @@
-<?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>{4a0dd677-931f-4728-afe5-b761149fc7eb}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\tests\test_opus_decode.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
+<?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>{4a0dd677-931f-4728-afe5-b761149fc7eb}</UniqueIdentifier>

+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

+    </Filter>

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\..\tests\test_opus_decode.c">

+      <Filter>Source Files</Filter>

+    </ClCompile>

+  </ItemGroup>

 </Project>
\ No newline at end of file
diff --git a/win32/VS2015/test_opus_encode.vcxproj b/win32/VS2015/test_opus_encode.vcxproj
index 405efee..b10eaf2 100644
--- a/win32/VS2015/test_opus_encode.vcxproj
+++ b/win32/VS2015/test_opus_encode.vcxproj
@@ -1,172 +1,172 @@
-<?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>
-    </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_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>
-    </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="..\..\tests\opus_encode_regressions.c" />
-    <ClCompile Include="..\..\tests\test_opus_encode.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="opus.vcxproj">
-      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{84DAA768-1A38-4312-BB61-4C78BB59E5B8}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>test_opus_api</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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>
-    <PlatformToolset>v140</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <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" />
-  <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" />
-  <ItemDefinitionGroup />
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?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>

+    </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_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>

+    </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="..\..\tests\opus_encode_regressions.c" />

+    <ClCompile Include="..\..\tests\test_opus_encode.c" />

+  </ItemGroup>

+  <ItemGroup>

+    <ProjectReference Include="opus.vcxproj">

+      <Project>{219ec965-228a-1824-174d-96449d05f88a}</Project>

+    </ProjectReference>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{84DAA768-1A38-4312-BB61-4C78BB59E5B8}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>test_opus_api</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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>

+    <PlatformToolset>v140</PlatformToolset>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseDLL|x64'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <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" />

+  <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" />

+  <ItemDefinitionGroup />

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

 </Project>
\ No newline at end of file
diff --git a/win32/VS2015/test_opus_encode.vcxproj.filters b/win32/VS2015/test_opus_encode.vcxproj.filters
index 4ed3bb9..f047763 100644
--- a/win32/VS2015/test_opus_encode.vcxproj.filters
+++ b/win32/VS2015/test_opus_encode.vcxproj.filters
@@ -1,17 +1,17 @@
-<?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>{546c8d9a-103e-4f78-972b-b44e8d3c8aba}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <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>
+<?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>{546c8d9a-103e-4f78-972b-b44e8d3c8aba}</UniqueIdentifier>

+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

+    </Filter>

+  </ItemGroup>

+  <ItemGroup>

+    <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 1def746..aea5573 100644
--- a/win32/genversion.bat
+++ b/win32/genversion.bat
@@ -1,37 +1,37 @@
-@echo off
-
-setlocal enableextensions enabledelayedexpansion
-
-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%"=="" set version=!version:~1! && goto :gotversion
-
-if exist "%~dp0..\package_version" goto :getversion
-
-echo Git cannot be found, nor can package_version. Generating unknown version.
-
-set version=unknown
-
-goto :gotversion
-
-:getversion
-
-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%"
-
-echo %version_out%> "%~1_temp"
-
-echo n | comp "%~1_temp" "%~1" > NUL 2> NUL
-
-if not errorlevel 1 goto exit
-
-copy /y "%~1_temp" "%~1"
-
-:exit
-
-del "%~1_temp"
+@echo off

+

+setlocal enableextensions enabledelayedexpansion

+

+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%"=="" set version=!version:~1! && goto :gotversion

+

+if exist "%~dp0..\package_version" goto :getversion

+

+echo Git cannot be found, nor can package_version. Generating unknown version.

+

+set version=unknown

+

+goto :gotversion

+

+:getversion

+

+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%"

+

+echo %version_out%> "%~1_temp"

+

+echo n | comp "%~1_temp" "%~1" > NUL 2> NUL

+

+if not errorlevel 1 goto exit

+

+copy /y "%~1_temp" "%~1"

+

+:exit

+

+del "%~1_temp"