diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c
index 2ba98869c596c00e5706304147dbae6112f41c91..7df94b567f40d4765993cb513af40d4ea8fa8a93 100644
--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -424,10 +424,12 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
       opus_val16 fade = Q15ONE;
       int pitch_index;
       VARDECL(opus_val32, etmp);
+      VARDECL(opus_val16, exc);
 
       if (loss_count == 0)
       {
-         opus_val16 lp_pitch_buf[DECODE_BUFFER_SIZE>>1];
+         VARDECL( opus_val16, lp_pitch_buf );
+         ALLOC( lp_pitch_buf, DECODE_BUFFER_SIZE>>1, opus_val16 );
          pitch_downsample(decode_mem, lp_pitch_buf, DECODE_BUFFER_SIZE, C);
          pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf,
                DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX,
@@ -440,14 +442,12 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
       }
 
       ALLOC(etmp, overlap, opus_val32);
+      ALLOC(exc, MAX_PERIOD, opus_val16);
       window = mode->window;
       c=0; do {
-         opus_val16 exc[MAX_PERIOD];
-         opus_val32 ac[LPC_ORDER+1];
          opus_val16 decay;
          opus_val16 attenuation;
          opus_val32 S1=0;
-         opus_val16 lpc_mem[LPC_ORDER];
          celt_sig *buf;
          int extrapolation_offset;
          int extrapolation_len;
@@ -461,6 +461,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
 
          if (loss_count == 0)
          {
+            opus_val32 ac[LPC_ORDER+1];
             /* Compute LPC coefficients for the last MAX_PERIOD samples before
                the first loss so we can work in the excitation-filter domain. */
             _celt_autocorr(exc, ac, window, overlap, LPC_ORDER, MAX_PERIOD);
@@ -487,14 +488,17 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
          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++)
          {
-            lpc_mem[i] =
-                  ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
+            opus_val16 lpc_mem[LPC_ORDER];
+            for (i=0;i<LPC_ORDER;i++)
+            {
+               lpc_mem[i] =
+                     ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
+            }
+            /* Compute the excitation for exc_length samples before the loss. */
+            celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
+                  exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem);
          }
-         /* Compute the excitation for exc_length samples before the loss. */
-         celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
-               exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem);
 
          /* Check if the waveform is decaying, and if so how fast.
             We do this to avoid adding energy when concealing in a segment
@@ -547,14 +551,18 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_R
             S1 += SHR32(MULT16_16(tmp, tmp), 8);
          }
 
-         /* Copy the last decoded samples (prior to the overlap region) to
-            synthesis filter memory so we can have a continuous signal. */
-         for (i=0;i<LPC_ORDER;i++)
-            lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT);
-         /* Apply the synthesis filter to convert the excitation back into the
-            signal domain. */
-         celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
-               buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER, lpc_mem);
+         {
+            opus_val16 lpc_mem[LPC_ORDER];
+            /* Copy the last decoded samples (prior to the overlap region) to
+               synthesis filter memory so we can have a continuous signal. */
+            for (i=0;i<LPC_ORDER;i++)
+               lpc_mem[i] = ROUND16(buf[DECODE_BUFFER_SIZE-N-1-i], SIG_SHIFT);
+            /* Apply the synthesis filter to convert the excitation back into
+               the signal domain. */
+            celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
+                  buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
+                  lpc_mem);
+         }
 
          /* Check if the synthesis energy is higher than expected, which can
             happen with the signal changes during our window. If so,
diff --git a/silk/CNG.c b/silk/CNG.c
index d0a619c163d44fb35606fbacb04ecbcb1c4387ff..cc1428e1a6037343d66b1b3e0fc3428272791e21 100644
--- a/silk/CNG.c
+++ b/silk/CNG.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 /* Generates excitation for CNG LPC synthesis */
 static inline void silk_CNG_exc(
@@ -86,8 +87,8 @@ void silk_CNG(
     opus_int   i, subfr;
     opus_int32 sum_Q6, max_Gain_Q16;
     opus_int16 A_Q12[ MAX_LPC_ORDER ];
-    opus_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ];
     silk_CNG_struct *psCNG = &psDec->sCNG;
+    SAVE_STACK;
 
     if( psDec->fs_kHz != psCNG->fs_kHz ) {
         /* Reset state */
@@ -123,6 +124,9 @@ void silk_CNG(
 
     /* Add CNG when packet is lost or during DTX */
     if( psDec->lossCnt ) {
+        VARDECL( opus_int32, CNG_sig_Q10 );
+
+        ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );
 
         /* Generate CNG excitation */
         silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
@@ -164,4 +168,5 @@ void silk_CNG(
     } else {
         silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order *  sizeof( opus_int32 ) );
     }
+    RESTORE_STACK;
 }
diff --git a/silk/NLSF_encode.c b/silk/NLSF_encode.c
index 52a263d97a895ef678bb42c64fe2d233c3501b9f..0f22372be2c5f55c612c26ea504e6f1a109b91d7 100644
--- a/silk/NLSF_encode.c
+++ b/silk/NLSF_encode.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 /***********************/
 /* NLSF vector encoder */
@@ -46,10 +47,10 @@ opus_int32 silk_NLSF_encode(                                    /* O    Returns
 {
     opus_int         i, s, ind1, bestIndex, prob_Q8, bits_q7;
     opus_int32       W_tmp_Q9;
-    opus_int32       err_Q26[      NLSF_VQ_MAX_VECTORS ];
-    opus_int32       RD_Q25[       NLSF_VQ_MAX_SURVIVORS ];
-    opus_int         tempIndices1[ NLSF_VQ_MAX_SURVIVORS ];
-    opus_int8        tempIndices2[ NLSF_VQ_MAX_SURVIVORS * MAX_LPC_ORDER ];
+    VARDECL( opus_int32, err_Q26 );
+    VARDECL( opus_int32, RD_Q25 );
+    VARDECL( opus_int, tempIndices1 );
+    VARDECL( opus_int8, tempIndices2 );
     opus_int16       res_Q15[      MAX_LPC_ORDER ];
     opus_int16       res_Q10[      MAX_LPC_ORDER ];
     opus_int16       NLSF_tmp_Q15[ MAX_LPC_ORDER ];
@@ -58,6 +59,7 @@ opus_int32 silk_NLSF_encode(                                    /* O    Returns
     opus_uint8       pred_Q8[      MAX_LPC_ORDER ];
     opus_int16       ec_ix[        MAX_LPC_ORDER ];
     const opus_uint8 *pCB_element, *iCDF_ptr;
+    SAVE_STACK;
 
     silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );
     silk_assert( signalType >= 0 && signalType <= 2 );
@@ -67,11 +69,16 @@ opus_int32 silk_NLSF_encode(                                    /* O    Returns
     silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
 
     /* First stage: VQ */
+    ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 );
     silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );
 
     /* Sort the quantization errors */
+    ALLOC( tempIndices1, nSurvivors, opus_int );
     silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
 
+    ALLOC( RD_Q25, nSurvivors, opus_int32 );
+    ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
+
     /* Loop over survivors */
     for( s = 0; s < nSurvivors; s++ ) {
         ind1 = tempIndices1[ s ];
@@ -125,4 +132,5 @@ opus_int32 silk_NLSF_encode(                                    /* O    Returns
     silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
 
     return RD_Q25[ 0 ];
+    RESTORE_STACK;
 }
diff --git a/silk/NSQ.c b/silk/NSQ.c
index b49cdf58aff8582657056e3fa23fdbc43a5dabbf..2a22d0fd5bfa31a70a64500e4988eab87c4f770c 100644
--- a/silk/NSQ.c
+++ b/silk/NSQ.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 static inline void silk_nsq_scale_states(
     const silk_encoder_state *psEncC,           /* I    Encoder State                   */
@@ -88,11 +89,12 @@ void silk_NSQ(
     opus_int            k, lag, start_idx, LSF_interpolation_flag;
     const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;
     opus_int16          *pxq;
-    opus_int32          sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
-    opus_int16          sLTP[     2 * MAX_FRAME_LENGTH ];
+    VARDECL( opus_int32, sLTP_Q15 );
+    VARDECL( opus_int16, sLTP );
     opus_int32          HarmShapeFIRPacked_Q14;
     opus_int            offset_Q10;
-    opus_int32          x_sc_Q10[ MAX_SUB_FRAME_LENGTH ];
+    VARDECL( opus_int32, x_sc_Q10 );
+    SAVE_STACK;
 
     NSQ->rand_seed = psIndices->Seed;
 
@@ -109,6 +111,10 @@ void silk_NSQ(
         LSF_interpolation_flag = 1;
     }
 
+    ALLOC( sLTP_Q15,
+           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
+    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
     /* Set up pointers to start of sub frame */
     NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
     NSQ->sLTP_buf_idx     = psEncC->ltp_mem_length;
@@ -160,6 +166,7 @@ void silk_NSQ(
     /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
+    RESTORE_STACK;
 }
 
 /***********************************/
diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c
index b877fa96becddb1a33d64da93884e86b0c64bf04..b2cfb40b9f0aaf7a4a0ecfcb925da5772cd065b6 100644
--- a/silk/NSQ_del_dec.c
+++ b/silk/NSQ_del_dec.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 typedef struct {
     opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
@@ -54,6 +55,8 @@ typedef struct {
     opus_int32 LPC_exc_Q14;
 } NSQ_sample_struct;
 
+typedef NSQ_sample_struct  NSQ_sample_pair[ 2 ];
+
 static inline void silk_nsq_del_dec_scale_states(
     const silk_encoder_state *psEncC,               /* I    Encoder State                       */
     silk_nsq_state      *NSQ,                       /* I/O  NSQ state                           */
@@ -123,17 +126,18 @@ void silk_NSQ_del_dec(
 {
     opus_int            i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
     opus_int            last_smple_idx, smpl_buf_idx, decisionDelay;
-    const opus_int16 	*A_Q12, *B_Q14, *AR_shp_Q13;
+    const opus_int16    *A_Q12, *B_Q14, *AR_shp_Q13;
     opus_int16          *pxq;
-    opus_int32          sLTP_Q15[ 2 * MAX_FRAME_LENGTH ];
-    opus_int16          sLTP[     2 * MAX_FRAME_LENGTH ];
+    VARDECL( opus_int32, sLTP_Q15 );
+    VARDECL( opus_int16, sLTP );
     opus_int32          HarmShapeFIRPacked_Q14;
     opus_int            offset_Q10;
     opus_int32          RDmin_Q10, Gain_Q10;
-    opus_int32          x_sc_Q10[ MAX_SUB_FRAME_LENGTH ];
-    opus_int32          delayedGain_Q10[  DECISION_DELAY ];
-    NSQ_del_dec_struct  psDelDec[ MAX_DEL_DEC_STATES ];
+    VARDECL( opus_int32, x_sc_Q10 );
+    VARDECL( opus_int32, delayedGain_Q10 );
+    VARDECL( NSQ_del_dec_struct, psDelDec );
     NSQ_del_dec_struct  *psDD;
+    SAVE_STACK;
 
     /* Set unvoiced lag to the previous one, overwrite later for voiced */
     lag = NSQ->lagPrev;
@@ -141,6 +145,7 @@ void silk_NSQ_del_dec(
     silk_assert( NSQ->prev_gain_Q16 != 0 );
 
     /* Initialize delayed decision states */
+    ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
     silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
     for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
         psDD                 = &psDelDec[ k ];
@@ -175,6 +180,11 @@ void silk_NSQ_del_dec(
         LSF_interpolation_flag = 1;
     }
 
+    ALLOC( sLTP_Q15,
+           psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+    ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
+    ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
+    ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
     /* Set up pointers to start of sub frame */
     pxq                   = &NSQ->xq[ psEncC->ltp_mem_length ];
     NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
@@ -287,6 +297,7 @@ void silk_NSQ_del_dec(
     /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
     silk_memmove( NSQ->xq,           &NSQ->xq[           psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
     silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
+    RESTORE_STACK;
 }
 
 /******************************************/
@@ -328,11 +339,13 @@ static inline void silk_noise_shape_quantizer_del_dec(
     opus_int32   q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
     opus_int32   tmp1, tmp2, sLF_AR_shp_Q14;
     opus_int32   *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
-    NSQ_sample_struct  psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
+    VARDECL( NSQ_sample_pair, psSampleState );
     NSQ_del_dec_struct *psDD;
     NSQ_sample_struct  *psSS;
+    SAVE_STACK;
 
     silk_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 ];
     pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
@@ -614,6 +627,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
         psDD = &psDelDec[ k ];
         silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
     }
+    RESTORE_STACK;
 }
 
 static inline void silk_nsq_del_dec_scale_states(
diff --git a/silk/VAD.c b/silk/VAD.c
index bac89b44477187c83a4a2d105d738b824f412c35..29663369c94edc486bb25882107c8f432ff8972b 100644
--- a/silk/VAD.c
+++ b/silk/VAD.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 /* Silk VAD noise level estimation */
 static inline void silk_VAD_GetNoiseLevels(
@@ -82,15 +83,19 @@ opus_int silk_VAD_GetSA_Q8(                                     /* O    Return v
 )
 {
     opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
-    opus_int   decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
+    opus_int   decimated_framelength1, decimated_framelength2;
+    opus_int   decimated_framelength;
+    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
     opus_int32 sumSquared, smooth_coef_Q16;
     opus_int16 HPstateTmp;
-    opus_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ];
+    VARDECL( opus_int16, X );
     opus_int32 Xnrg[ VAD_N_BANDS ];
     opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
     opus_int32 speech_nrg, x_tmp;
+    opus_int   X_offset[ VAD_N_BANDS ];
     opus_int   ret = 0;
     silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
+    SAVE_STACK;
 
     /* Safety checks */
     silk_assert( VAD_N_BANDS == 4 );
@@ -101,26 +106,46 @@ opus_int silk_VAD_GetSA_Q8(                                     /* O    Return v
     /***********************/
     /* Filter and Decimate */
     /***********************/
+    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
+    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
+    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
+    /* Decimate into 4 bands:
+       0       L      3L       L              3L                             5L
+               -      --       -              --                             --
+               8       8       2               4                              4
+
+       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |
+
+       They're arranged to allow the minimal ( frame_length / 4 ) extra
+       scratch space during the downsampling process */
+    X_offset[ 0 ] = 0;
+    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
+    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
+    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
+    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
+
     /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
-    silk_ana_filt_bank_1( pIn,          &psSilk_VAD->AnaState[  0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], psEncC->frame_length );
+    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
+        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
 
     /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
-    silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], silk_RSHIFT( psEncC->frame_length, 1 ) );
+    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
+        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
 
     /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
-    silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], silk_RSHIFT( psEncC->frame_length, 2 ) );
+    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
+        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
 
     /*********************************************/
     /* HP filter on lowest band (differentiator) */
     /*********************************************/
-    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
-    X[ 0 ][ decimated_framelength - 1 ] = silk_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 );
-    HPstateTmp = X[ 0 ][ decimated_framelength - 1 ];
+    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
+    HPstateTmp = X[ decimated_framelength - 1 ];
     for( i = decimated_framelength - 1; i > 0; i-- ) {
-        X[ 0 ][ i - 1 ]  = silk_RSHIFT( X[ 0 ][ i - 1 ], 1 );
-        X[ 0 ][ i ]     -= X[ 0 ][ i - 1 ];
+        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
+        X[ i ]     -= X[ i - 1 ];
     }
-    X[ 0 ][ 0 ] -= psSilk_VAD->HPstate;
+    X[ 0 ] -= psSilk_VAD->HPstate;
     psSilk_VAD->HPstate = HPstateTmp;
 
     /*************************************/
@@ -142,7 +167,8 @@ opus_int silk_VAD_GetSA_Q8(                                     /* O    Return v
             for( i = 0; i < dec_subframe_length; i++ ) {
                 /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */
                 /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */
-                x_tmp = silk_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 );
+                x_tmp = silk_RSHIFT(
+                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
                 sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
 
                 /* Safety check */
@@ -264,6 +290,7 @@ opus_int silk_VAD_GetSA_Q8(                                     /* O    Return v
     }
 
     return( ret );
+    RESTORE_STACK;
 }
 
 /**************************/
diff --git a/silk/control_codec.c b/silk/control_codec.c
index ecc338cec65d6e32fbe09f7c6312a275329de6d5..9159b1864a803749de9d649ddbc18bddaf5590b1 100644
--- a/silk/control_codec.c
+++ b/silk/control_codec.c
@@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "main_FLP.h"
 #define silk_encoder_state_Fxx      silk_encoder_state_FLP
 #endif
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 #include "pitch_est_defines.h"
 
@@ -138,6 +139,7 @@ static opus_int silk_setup_resamplers(
 {
     opus_int   ret = SILK_NO_ERROR;
     opus_int32 nSamples_temp;
+    SAVE_STACK;
 
     if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz )
     {
@@ -145,35 +147,38 @@ static opus_int silk_setup_resamplers(
             /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
             ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );
         } else {
-            /* Allocate worst case space for temporary upsampling, 8 to 48 kHz, so a factor 6 */
-            opus_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * MAX_API_FS_KHZ ];
-            silk_resampler_state_struct  temp_resampler_state;
+            VARDECL( opus_int16, x_buf_API_fs_Hz );
+            VARDECL( silk_resampler_state_struct, temp_resampler_state );
 #ifdef FIXED_POINT
             opus_int16 *x_bufFIX = psEnc->x_buf;
 #else
-            opus_int16 x_bufFIX[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];
+            VARDECL( opus_int16, x_bufFIX );
 #endif
+            opus_int32 nAPI_Samples_temp;
 
             nSamples_temp = silk_LSHIFT( psEnc->sCmn.frame_length, 1 ) + LA_SHAPE_MS * psEnc->sCmn.fs_kHz;
 
 #ifndef FIXED_POINT
+            ALLOC( x_bufFIX, nSamples_temp, opus_int16 );
             silk_float2short_array( x_bufFIX, psEnc->x_buf, nSamples_temp );
 #endif
 
             /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
-            ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
+            ALLOC( temp_resampler_state, 1, silk_resampler_state_struct );
+            ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
 
-            /* Temporary resampling of x_buf data to API_fs_Hz */
-            ret += silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp );
+            /* Calculate number of samples to temporarily upsample */
+            nAPI_Samples_temp = silk_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) );
 
-            /* Calculate number of samples that has been temporarily upsampled */
-            nSamples_temp = silk_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) );
+            /* Temporary resampling of x_buf data to API_fs_Hz */
+            ALLOC( x_buf_API_fs_Hz, nAPI_Samples_temp, opus_int16 );
+            ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp );
 
             /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
             ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );
 
             /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
-            ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nSamples_temp );
+            ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nAPI_Samples_temp );
 
 #ifndef FIXED_POINT
             silk_short2float_array( psEnc->x_buf, x_bufFIX, ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * fs_kHz );
@@ -183,6 +188,7 @@ static opus_int silk_setup_resamplers(
 
     psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
 
+    RESTORE_STACK;
     return ret;
 }
 
diff --git a/silk/enc_API.c b/silk/enc_API.c
index 325e16ada4c0efbb6c681a25e81981d0c3381974..e1edcd11aebb736c3cfd7d71ecebe9451e44d6d3 100644
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include "API.h"
 #include "control.h"
 #include "typedef.h"
+#include "stack_alloc.h"
 #include "structs.h"
 #include "tuning_parameters.h"
 #ifdef FIXED_POINT
@@ -146,18 +147,21 @@ opus_int silk_Encode(                                   /* O    Returns error co
 )
 {
     opus_int   n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
-    opus_int   nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0;
+    opus_int   nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
+    opus_int   nSamplesFromInput = 0, nSamplesFromInputMax;
     opus_int   speech_act_thr_for_switch_Q8;
     opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
     silk_encoder *psEnc = ( silk_encoder * )encState;
-    opus_int16 buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ];
+    VARDECL( opus_int16, buf );
     opus_int transition, curr_block, tot_blocks;
+    SAVE_STACK;
 
     psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
 
     /* Check values in encoder control structure */
     if( ( ret = check_control_input( encControl ) != 0 ) ) {
         silk_assert( 0 );
+        RESTORE_STACK;
         return ret;
     }
 
@@ -192,6 +196,7 @@ opus_int silk_Encode(                                   /* O    Returns error co
         /* Only accept input length of 10 ms */
         if( nBlocksOf10ms != 1 ) {
             silk_assert( 0 );
+            RESTORE_STACK;
             return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
         }
         /* Reset Encoder */
@@ -212,11 +217,13 @@ opus_int silk_Encode(                                   /* O    Returns error co
         /* Only accept input lengths that are a multiple of 10 ms */
         if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
             silk_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 );
+            RESTORE_STACK;
             return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
         }
     }
@@ -227,6 +234,7 @@ opus_int silk_Encode(                                   /* O    Returns error co
         opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
         if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
             silk_assert( 0 );
+            RESTORE_STACK;
             return ret;
         }
         if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
@@ -239,9 +247,16 @@ opus_int silk_Encode(                                   /* O    Returns error co
     silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
 
     /* Input buffering/resampling and encoding */
+    nSamplesToBufferMax =
+        10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
+    nSamplesFromInputMax =
+        silk_DIV32_16( nSamplesToBufferMax *
+                           psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
+                       psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
+    ALLOC( buf, nSamplesFromInputMax, opus_int16 );
     while( 1 ) {
         nSamplesToBuffer  = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
-        nSamplesToBuffer  = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz );
+        nSamplesToBuffer  = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
         nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
         /* Resample and write to buffer */
         if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
@@ -530,6 +545,7 @@ opus_int silk_Encode(                                   /* O    Returns error co
         }
     }
 
+    RESTORE_STACK;
     return ret;
 }
 
diff --git a/silk/encode_pulses.c b/silk/encode_pulses.c
index b01b5853620d097fa3c53c2ef96719c35f53e514..301b5618a1cf3f2de4235e3fc26b73d4e64d0cc5 100644
--- a/silk/encode_pulses.c
+++ b/silk/encode_pulses.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 /*********************************************/
 /* Encode quantization indices of excitation */
@@ -66,14 +67,15 @@ void silk_encode_pulses(
 {
     opus_int   i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
     opus_int32 abs_q, minSumBits_Q5, sumBits_Q5;
-    opus_int   abs_pulses[ MAX_FRAME_LENGTH ];
-    opus_int   sum_pulses[ MAX_NB_SHELL_BLOCKS ];
-    opus_int   nRshifts[   MAX_NB_SHELL_BLOCKS ];
+    VARDECL( opus_int, abs_pulses );
+    VARDECL( opus_int, sum_pulses );
+    VARDECL( opus_int, nRshifts );
     opus_int   pulses_comb[ 8 ];
     opus_int   *abs_pulses_ptr;
     const opus_int8 *pulses_ptr;
     const opus_uint8 *cdf_ptr;
     const opus_uint8 *nBits_ptr;
+    SAVE_STACK;
 
     silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/
 
@@ -90,6 +92,8 @@ void silk_encode_pulses(
     }
 
     /* Take the absolute value of the pulses */
+    ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int );
+    silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) );
     for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) {
         abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] );
         abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] );
@@ -98,6 +102,8 @@ void silk_encode_pulses(
     }
 
     /* Calc sum pulses per shell code frame */
+    ALLOC( sum_pulses, iter, opus_int );
+    ALLOC( nRshifts, iter, opus_int );
     abs_pulses_ptr = abs_pulses;
     for( i = 0; i < iter; i++ ) {
         nRshifts[ i ] = 0;
@@ -196,4 +202,5 @@ void silk_encode_pulses(
     /* Encode signs */
     /****************/
     silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses );
+    RESTORE_STACK;
 }
diff --git a/silk/fixed/encode_frame_FIX.c b/silk/fixed/encode_frame_FIX.c
index a37a9f21299587bd292a2c6b520722e3e3b268bd..075cd994aa95fbfc46932dd89e0faac097781745 100644
--- a/silk/fixed/encode_frame_FIX.c
+++ b/silk/fixed/encode_frame_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 
 /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */
@@ -84,9 +85,7 @@ opus_int silk_encode_frame_FIX(
 {
     silk_encoder_control_FIX sEncCtrl;
     opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
-    opus_int16   *x_frame, *res_pitch_frame;
-    opus_int32   xfw_Q3[ MAX_FRAME_LENGTH ];
-    opus_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
+    opus_int16   *x_frame;
     ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
     silk_nsq_state sNSQ_copy, sNSQ_copy2;
     opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
@@ -95,7 +94,7 @@ opus_int silk_encode_frame_FIX(
     opus_int16   ec_prevLagIndex_copy;
     opus_int     ec_prevSignalType_copy;
     opus_int8    LastGainIndex_copy2;
-    opus_uint8   ec_buf_copy[ 1275 ];
+    SAVE_STACK;
 
     /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
     LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
@@ -105,9 +104,8 @@ opus_int silk_encode_frame_FIX(
     /**************************************************************/
     /* Set up Input Pointers, and insert frame in input buffer   */
     /*************************************************************/
-    /* pointers aligned with start of frame to encode */
-    x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */
-    res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */
+    /* start of frame to encode */
+    x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
 
     /***************************************/
     /* Ensure smooth bandwidth transitions */
@@ -120,6 +118,17 @@ opus_int silk_encode_frame_FIX(
     silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
 
     if( !psEnc->sCmn.prefillFlag ) {
+        VARDECL( opus_int32, xfw_Q3 );
+        VARDECL( opus_int16, res_pitch );
+        VARDECL( opus_uint8, ec_buf_copy );
+        opus_int16 *res_pitch_frame;
+
+        ALLOC( res_pitch,
+               psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
+                   + psEnc->sCmn.ltp_mem_length, opus_int16 );
+        /* start of pitch LPC residual frame */
+        res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
+
         /*****************************************/
         /* Find pitch lags, initial LPC analysis */
         /*****************************************/
@@ -143,6 +152,7 @@ opus_int silk_encode_frame_FIX(
         /*****************************************/
         /* Prefiltering for noise shaper         */
         /*****************************************/
+        ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 );
         silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame );
 
         /****************************************/
@@ -164,6 +174,7 @@ opus_int silk_encode_frame_FIX(
         seed_copy = psEnc->sCmn.indices.Seed;
         ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
         ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
+        ALLOC( ec_buf_copy, 1275, opus_uint8 );
         for( iter = 0; ; iter++ ) {
             if( gainsID == gainsID_lower ) {
                 nBits = nBits_lower;
@@ -299,6 +310,7 @@ opus_int silk_encode_frame_FIX(
     if( psEnc->sCmn.prefillFlag ) {
         /* No payload */
         *pnBytesOut = 0;
+        RESTORE_STACK;
         return ret;
     }
 
@@ -309,6 +321,7 @@ opus_int silk_encode_frame_FIX(
     /* Payload size */
     *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
 
+    RESTORE_STACK;
     return ret;
 }
 
diff --git a/silk/fixed/find_LPC_FIX.c b/silk/fixed/find_LPC_FIX.c
index 0ed7e846174086cad8fdc1a269cc720be85bbeed..eae89d26392cd6c1dbe0ebd8d9ce115d4116c6bd 100644
--- a/silk/fixed/find_LPC_FIX.c
+++ b/silk/fixed/find_LPC_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 
 /* Finds LPC vector from correlations, and converts to NLSF */
@@ -51,7 +52,7 @@ void silk_find_LPC_FIX(
     opus_int     res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
     opus_int16   a_tmp_Q12[ MAX_LPC_ORDER ];
     opus_int16   NLSF0_Q15[ MAX_LPC_ORDER ];
-    opus_int16   LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];
+    SAVE_STACK;
 
     subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
 
@@ -62,6 +63,8 @@ void silk_find_LPC_FIX(
     silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );
 
     if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
+        VARDECL( opus_int16, LPC_res );
+
         /* Optimal solution for last 10 ms */
         silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder );
 
@@ -81,6 +84,8 @@ void silk_find_LPC_FIX(
         /* Convert to NLSFs */
         silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );
 
+        ALLOC( LPC_res, 2 * subfr_length, opus_int16 );
+
         /* Search over interpolation indices to find the one with lowest residual energy */
         for( k = 3; k >= 0; k-- ) {
             /* Interpolate NLSFs for first half */
@@ -142,4 +147,5 @@ void silk_find_LPC_FIX(
     }
 
     silk_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 238cb1dcd8c3fa3fedf647e958fa2db89b86b0bd..f7c80961f2d77eb4d08ffe8608b746e72509328d 100644
--- a/silk/fixed/find_pitch_lags_FIX.c
+++ b/silk/fixed/find_pitch_lags_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 
 /* Find pitch lags */
@@ -43,11 +44,13 @@ void silk_find_pitch_lags_FIX(
     opus_int   buf_len, i, scale;
     opus_int32 thrhld_Q13, res_nrg;
     const opus_int16 *x_buf, *x_buf_ptr;
-    opus_int16 Wsig[      FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr;
+    VARDECL( opus_int16, Wsig );
+    opus_int16 *Wsig_ptr;
     opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
     opus_int16 rc_Q15[    MAX_FIND_PITCH_LPC_ORDER ];
     opus_int32 A_Q24[     MAX_FIND_PITCH_LPC_ORDER ];
     opus_int16 A_Q12[     MAX_FIND_PITCH_LPC_ORDER ];
+    SAVE_STACK;
 
     /******************************************/
     /* Set up buffer lengths etc based on Fs  */
@@ -65,6 +68,8 @@ void silk_find_pitch_lags_FIX(
 
     /* Calculate windowed signal */
 
+    ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
+
     /* First LA_LTP samples */
     x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
     Wsig_ptr  = Wsig;
@@ -134,4 +139,5 @@ void silk_find_pitch_lags_FIX(
         psEnc->sCmn.indices.contourIndex = 0;
         psEnc->LTPCorr_Q15 = 0;
     }
+    RESTORE_STACK;
 }
diff --git a/silk/fixed/find_pred_coefs_FIX.c b/silk/fixed/find_pred_coefs_FIX.c
index 997989b522321a70daa7e642f5cd4d8b9973c072..6fbd86d43549311e3707888aa34b9221394cec09 100644
--- a/silk/fixed/find_pred_coefs_FIX.c
+++ b/silk/fixed/find_pred_coefs_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 
 void silk_find_pred_coefs_FIX(
     silk_encoder_state_FIX          *psEnc,                                 /* I/O  encoder state                                                               */
@@ -40,13 +41,14 @@ void silk_find_pred_coefs_FIX(
 )
 {
     opus_int         i;
-    opus_int32       WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
     opus_int32       invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];
     opus_int16       NLSF_Q15[ MAX_LPC_ORDER ];
     const opus_int16 *x_ptr;
-    opus_int16       *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
+    opus_int16       *x_pre_ptr;
+    VARDECL( opus_int16, LPC_in_pre );
     opus_int32       tmp, min_gain_Q16, minInvGain_Q30;
     opus_int         LTP_corrs_rshift[ MAX_NB_SUBFR ];
+    SAVE_STACK;
 
     /* weighting for weighted least squares */
     min_gain_Q16 = silk_int32_MAX >> 6;
@@ -71,12 +73,19 @@ void silk_find_pred_coefs_FIX(
         local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
     }
 
+    ALLOC( LPC_in_pre,
+           psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
+               + psEnc->sCmn.frame_length, opus_int16 );
     if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+        VARDECL( opus_int32, WLTP );
+
         /**********/
         /* VOICED */
         /**********/
         silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
 
+        ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
+
         /* LTP analysis */
         silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7,
             res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length,
@@ -133,4 +142,5 @@ void silk_find_pred_coefs_FIX(
 
     /* Copy to prediction struct for use in next frame for interpolation */
     silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
+    RESTORE_STACK;
 }
diff --git a/silk/fixed/noise_shape_analysis_FIX.c b/silk/fixed/noise_shape_analysis_FIX.c
index d230e48d84ee9264b962c5d14c6e538ede3b38a2..fa6684fe38ec47ee10aa2ec0c6ddc0ae34bf5640 100644
--- a/silk/fixed/noise_shape_analysis_FIX.c
+++ b/silk/fixed/noise_shape_analysis_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 
 /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a   */
@@ -156,8 +157,9 @@ void silk_noise_shape_analysis_FIX(
     opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
     opus_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];
     opus_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];
-    opus_int16   x_windowed[    SHAPE_LPC_WIN_MAX ];
+    VARDECL( opus_int16, x_windowed );
     const opus_int16 *x_ptr, *pitch_res_ptr;
+    SAVE_STACK;
 
     /* Point to start of first LPC analysis block */
     x_ptr = x - psEnc->sCmn.la_shape;
@@ -258,6 +260,7 @@ void silk_noise_shape_analysis_FIX(
     /********************************************/
     /* Compute noise shaping AR coefs and gains */
     /********************************************/
+    ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
     for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
         /* Apply window: sine slope followed by flat part followed by cosine slope */
         opus_int shift, slope_part, flat_part;
@@ -437,4 +440,5 @@ void silk_noise_shape_analysis_FIX(
         psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
         psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );
     }
+    RESTORE_STACK;
 }
diff --git a/silk/fixed/pitch_analysis_core_FIX.c b/silk/fixed/pitch_analysis_core_FIX.c
index ccf92349d778c8d26e68208e65336bd9da06a441..dbef3383767ea8e8186cb72025666ecb0ba29c7b 100644
--- a/silk/fixed/pitch_analysis_core_FIX.c
+++ b/silk/fixed/pitch_analysis_core_FIX.c
@@ -34,15 +34,29 @@ POSSIBILITY OF SUCH DAMAGE.
 ********************************************************** */
 #include "SigProc_FIX.h"
 #include "pitch_est_defines.h"
+#include "stack_alloc.h"
 #include "debug.h"
 
 #define SCRATCH_SIZE    22
+#define SF_LENGTH_4KHZ  ( PE_SUBFR_LENGTH_MS * 4 )
+#define SF_LENGTH_8KHZ  ( PE_SUBFR_LENGTH_MS * 8 )
+#define MIN_LAG_4KHZ    ( PE_MIN_LAG_MS * 4 )
+#define MIN_LAG_8KHZ    ( PE_MIN_LAG_MS * 8 )
+#define MAX_LAG_4KHZ    ( PE_MAX_LAG_MS * 4 )
+#define MAX_LAG_8KHZ    ( PE_MAX_LAG_MS * 8 - 1 )
+#define CSTRIDE_4KHZ    ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ )
+#define CSTRIDE_8KHZ    ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) )
+#define D_COMP_MIN      ( MIN_LAG_8KHZ - 3 )
+#define D_COMP_MAX      ( MAX_LAG_8KHZ + 4 )
+#define D_COMP_STRIDE   ( D_COMP_MAX - D_COMP_MIN )
+
+typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ];
 
 /************************************************************/
 /* Internally used functions                                */
 /************************************************************/
 static void silk_P_Ana_calc_corr_st3(
-    opus_int32        cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* O 3 DIM correlation array */
+    silk_pe_stage3_vals cross_corr_st3[],              /* O 3 DIM correlation array */
     const opus_int16  frame[],                         /* I vector to correlate         */
     opus_int          start_lag,                       /* I lag offset to search around */
     opus_int          sf_length,                       /* I length of a 5 ms subframe   */
@@ -51,7 +65,7 @@ static void silk_P_Ana_calc_corr_st3(
 );
 
 static void silk_P_Ana_calc_energy_st3(
-    opus_int32        energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* O 3 DIM energy array */
+    silk_pe_stage3_vals energies_st3[],                /* O 3 DIM energy array */
     const opus_int16  frame[],                         /* I vector to calc energy in    */
     opus_int          start_lag,                       /* I lag offset to search around */
     opus_int          sf_length,                       /* I length of one 5 ms subframe */
@@ -76,30 +90,30 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
     const opus_int              nb_subfr            /* I    number of 5 ms subframes                                    */
 )
 {
-    opus_int16 frame_8kHz[ PE_MAX_FRAME_LENGTH_ST_2 ];
-    opus_int16 frame_4kHz[ PE_MAX_FRAME_LENGTH_ST_1 ];
+    VARDECL( opus_int16, frame_8kHz );
+    VARDECL( opus_int16, frame_4kHz );
     opus_int32 filt_state[ 6 ];
-    opus_int32 scratch_mem[ 3 * PE_MAX_FRAME_LENGTH ];
-    opus_int16 *input_frame_ptr;
+    const opus_int16 *input_frame_ptr;
     opus_int   i, k, d, j;
-    opus_int16 C[ PE_MAX_NB_SUBFR ][ ( PE_MAX_LAG >> 1 ) + 5 ];
+    VARDECL( opus_int16, C );
     const opus_int16 *target_ptr, *basis_ptr;
     opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
     opus_int   d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;
-    opus_int16 d_comp[ ( PE_MAX_LAG >> 1 ) + 5 ];
+    VARDECL( opus_int16, d_comp );
     opus_int32 sum, threshold, lag_counter;
     opus_int   CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
     opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
-    opus_int32 energies_st3[  PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
-    opus_int32 crosscorr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
+    VARDECL( silk_pe_stage3_vals, energies_st3 );
+    VARDECL( silk_pe_stage3_vals, cross_corr_st3 );
     opus_int   frame_length, frame_length_8kHz, frame_length_4kHz;
-    opus_int   sf_length, sf_length_8kHz, sf_length_4kHz;
-    opus_int   min_lag, min_lag_8kHz, min_lag_4kHz;
-    opus_int   max_lag, max_lag_8kHz, max_lag_4kHz;
+    opus_int   sf_length;
+    opus_int   min_lag;
+    opus_int   max_lag;
     opus_int32 contour_bias_Q15, diff;
     opus_int   nb_cbk_search, cbk_size;
     opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
     const opus_int8 *Lag_CB_ptr;
+    SAVE_STACK;
     /* Check for valid sampling frequency */
     silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
 
@@ -115,16 +129,11 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
     frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
     frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
     sf_length         = PE_SUBFR_LENGTH_MS * Fs_kHz;
-    sf_length_4kHz    = PE_SUBFR_LENGTH_MS * 4;
-    sf_length_8kHz    = PE_SUBFR_LENGTH_MS * 8;
     min_lag           = PE_MIN_LAG_MS * Fs_kHz;
-    min_lag_4kHz      = PE_MIN_LAG_MS * 4;
-    min_lag_8kHz      = PE_MIN_LAG_MS * 8;
     max_lag           = PE_MAX_LAG_MS * Fs_kHz - 1;
-    max_lag_4kHz      = PE_MAX_LAG_MS * 4;
-    max_lag_8kHz      = PE_MAX_LAG_MS * 8 - 1;
 
     /* Resample from input sampled at Fs_kHz to 8 kHz */
+    ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 );
     if( Fs_kHz == 16 ) {
         silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
         silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );
@@ -138,6 +147,7 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
 
     /* Decimate again to 4 kHz */
     silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
+    ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 );
     silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );
 
     /* Low-pass filter */
@@ -162,84 +172,90 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
     /******************************************************************************
     * FIRST STAGE, operating in 4 khz
     ******************************************************************************/
-    silk_memset( C, 0, sizeof( opus_int16 ) * nb_subfr * ( ( PE_MAX_LAG >> 1 ) + 5) );
-    target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
+    ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 );
+    silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) );
+    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 );
+        silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
 
-        basis_ptr = target_ptr - min_lag_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 );
+        silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
 
         /* Calculate first vector products before loop */
-        cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr,  sf_length_8kHz );
-        normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz );
-        normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr,  basis_ptr, sf_length_8kHz ) );
-        normalizer = silk_ADD32( normalizer, silk_SMULBB( sf_length_8kHz, 4000 ) );
+        cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr,  SF_LENGTH_8KHZ );
+        normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ );
+        normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr,  basis_ptr, SF_LENGTH_8KHZ ) );
+        normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) );
 
-        C[ k ][ min_lag_4kHz ] = (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
+        matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) =
+            (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 );                      /* Q13 */
 
         /* From now on normalizer is computed recursively */
-        for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
+        for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) {
             basis_ptr--;
 
             /* 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 );
+            silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
 
-            cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+            cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ );
 
             /* Add contribution of new sample and remove contribution from oldest sample */
             normalizer = silk_ADD32( normalizer,
                 silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
-                silk_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] ) );
+                silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) );
 
-            C[ k ][ d ] = (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 );        /* Q13 */
+            matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) =
+                (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 );                  /* Q13 */
         }
         /* Update target pointer */
-        target_ptr += sf_length_8kHz;
+        target_ptr += SF_LENGTH_8KHZ;
     }
 
     /* Combine two subframes into single correlation measure and apply short-lag bias */
     if( nb_subfr == PE_MAX_NB_SUBFR ) {
-        for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
-            sum = (opus_int32)C[ 0 ][ i ] + (opus_int32) C[ 1 ][ i ];                           /* Q14 */
+        for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
+            sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ )
+                + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ );               /* Q14 */
             sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) );                                /* Q14 */
-            C[ 0 ][ i ] = (opus_int16)sum;                                                      /* Q14 */
+            C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum;                                            /* Q14 */
         }
     } else {
         /* Only short-lag bias */
-        for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
-            sum = silk_LSHIFT( (opus_int32)C[ 0 ][ i ], 1 );                                    /* Q14 */
+        for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
+            sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 );                          /* Q14 */
             sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) );                                /* Q14 */
-            C[ 0 ][ i ] = (opus_int16)sum;                                                      /* Q14 */
+            C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum;                                            /* Q14 */
         }
     }
 
     /* Sort */
     length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
     silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
-    silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
+    silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
+                                          length_d_srch );
 
     /* Escape if correlation is very low already here */
-    Cmax = (opus_int)C[ 0 ][ min_lag_4kHz ];                                                    /* Q14 */
+    Cmax = (opus_int)C[ 0 ];                                                    /* Q14 */
     if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) {
         silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
         *LTPCorr_Q15  = 0;
         *lagIndex     = 0;
         *contourIndex = 0;
+        RESTORE_STACK;
         return 1;
     }
 
     threshold = silk_SMULWB( search_thres1_Q16, Cmax );
     for( i = 0; i < length_d_srch; i++ ) {
         /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
-        if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
-            d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
+        if( C[ i ] > threshold ) {
+            d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 );
         } else {
             length_d_srch = i;
             break;
@@ -247,34 +263,37 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
     }
     silk_assert( length_d_srch > 0 );
 
-    for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
-        d_comp[ i ] = 0;
+    ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
+    for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
+        d_comp[ i - D_COMP_MIN ] = 0;
     }
     for( i = 0; i < length_d_srch; i++ ) {
-        d_comp[ d_srch[ i ] ] = 1;
+        d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1;
     }
 
     /* Convolution */
-    for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
-        d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
+    for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
+        d_comp[ i - D_COMP_MIN ] +=
+            d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ];
     }
 
     length_d_srch = 0;
-    for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
-        if( d_comp[ i + 1 ] > 0 ) {
+    for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) {
+        if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) {
             d_srch[ length_d_srch ] = i;
             length_d_srch++;
         }
     }
 
     /* Convolution */
-    for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
-        d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
+    for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
+        d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ]
+            + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ];
     }
 
     length_d_comp = 0;
-    for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
-        if( d_comp[ i ] > 0 ) {
+    for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) {
+        if( d_comp[ i - D_COMP_MIN ] > 0 ) {
             d_comp[ length_d_comp ] = i - 2;
             length_d_comp++;
         }
@@ -299,33 +318,37 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
     /*********************************************************************************
     * Find energy of each subframe projected onto its history, for a range of delays
     *********************************************************************************/
-    silk_memset( C, 0, PE_MAX_NB_SUBFR * ( ( PE_MAX_LAG >> 1 ) + 5 ) * sizeof( opus_int16 ) );
+    silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) );
 
     target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 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 );
+        silk_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 ), 1 );
+        energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ ), 1 );
         for( j = 0; j < length_d_comp; j++ ) {
             d = d_comp[ j ];
             basis_ptr = target_ptr - d;
 
             /* Check that we are within range of the array */
             silk_assert( basis_ptr >= frame_8kHz );
-            silk_assert( basis_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz );
+            silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
 
-            cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz );
+            cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ );
             if( cross_corr > 0 ) {
-                energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz );
-                C[ k ][ d ] = (opus_int16)silk_DIV32_varQ( cross_corr, silk_ADD32( energy_target, energy_basis ), 13 + 1 );        /* Q13 */
+                energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ );
+                matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) =
+                    (opus_int16)silk_DIV32_varQ( cross_corr,
+                                                 silk_ADD32( energy_target,
+                                                             energy_basis ),
+                                                 13 + 1 );                                      /* Q13 */
             } else {
-                C[ k ][ d ] = 0;
+                matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0;
             }
         }
-        target_ptr += sf_length_8kHz;
+        target_ptr += SF_LENGTH_8KHZ;
     }
 
     /* search over lag range and lags codebook */
@@ -369,8 +392,13 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
         for( j = 0; j < nb_cbk_search; j++ ) {
             CC[ j ] = 0;
             for( i = 0; i < nb_subfr; i++ ) {
+                opus_int d_subfr;
                 /* Try all codebooks */
-                CC[ j ] = CC[ j ] + (opus_int32)C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size ) ];
+                d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size );
+                CC[ j ] = CC[ j ]
+                    + (opus_int32)matrix_ptr( C, i,
+                                              d_subfr - ( MIN_LAG_8KHZ - 2 ),
+                                              CSTRIDE_8KHZ );
             }
         }
         /* Find best codebook */
@@ -402,7 +430,7 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
 
         if( CCmax_new_b > CCmax_b                                   &&  /* Find maximum biased correlation                  */
             CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 )  &&  /* Correlation needs to be high enough to be voiced */
-            silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz      /* Lag must be in range                             */
+            silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ      /* Lag must be in range                             */
          ) {
             CCmax_b = CCmax_new_b;
             CCmax   = CCmax_new;
@@ -417,6 +445,7 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
         *LTPCorr_Q15  = 0;
         *lagIndex     = 0;
         *contourIndex = 0;
+        RESTORE_STACK;
         return 1;
     }
 
@@ -425,21 +454,22 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
     silk_assert( *LTPCorr_Q15 >= 0 );
 
     if( Fs_kHz > 8 ) {
+        VARDECL( opus_int16, scratch_mem );
         /***************************************************************************/
         /* Scale input signal down to avoid correlations measures from overflowing */
         /***************************************************************************/
         /* find scaling as max scaling for each subframe */
         silk_sum_sqr_shift( &energy, &shift, frame, frame_length );
+        ALLOC( scratch_mem, shift > 0 ? frame_length : 0, opus_int16 );
         if( shift > 0 ) {
             /* Move signal to scratch mem because the input signal should be unchanged */
-            /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */
             shift = silk_RSHIFT( shift, 1 );
-            input_frame_ptr = (opus_int16*)scratch_mem;
             for( i = 0; i < frame_length; i++ ) {
-                input_frame_ptr[ i ] = silk_RSHIFT( frame[ i ], shift );
+                scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift );
             }
+            input_frame_ptr = scratch_mem;
         } else {
-            input_frame_ptr = (opus_int16*)frame;
+            input_frame_ptr = frame;
         }
 
         /* Search in original signal */
@@ -466,13 +496,6 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
         for( k = 0; k < nb_subfr; k++ ) {
             pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];
         }
-        /* Calculate the correlations and energies needed in stage 3 */
-        silk_P_Ana_calc_corr_st3(  crosscorr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
-        silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
-
-        lag_counter = 0;
-        silk_assert( lag == silk_SAT16( lag ) );
-        contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
 
         /* Set up codebook parameters according to complexity setting and frame length */
         if( nb_subfr == PE_MAX_NB_SUBFR ) {
@@ -485,6 +508,16 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
             Lag_CB_ptr      = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
         }
 
+        /* Calculate the correlations and energies needed in stage 3 */
+        ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
+        ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
+        silk_P_Ana_calc_corr_st3(  cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
+        silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity );
+
+        lag_counter = 0;
+        silk_assert( lag == silk_SAT16( lag ) );
+        contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
+
         target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
         energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length ), 1 );
         for( d = start_lag; d <= end_lag; d++ ) {
@@ -492,8 +525,12 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
                 cross_corr = 0;
                 energy     = energy_target;
                 for( k = 0; k < nb_subfr; k++ ) {
-                    cross_corr = silk_ADD32( cross_corr, crosscorr_st3[ k ][ j ][ lag_counter ] );
-                    energy     = silk_ADD32( energy, energies_st3[  k ][ j ][ lag_counter ] );
+                    cross_corr = silk_ADD32( cross_corr,
+                        matrix_ptr( cross_corr_st3, k, j,
+                                    nb_cbk_search )[ lag_counter ] );
+                    energy     = silk_ADD32( energy,
+                        matrix_ptr( energies_st3, k, j,
+                                    nb_cbk_search )[ lag_counter ] );
                     silk_assert( energy >= 0 );
                 }
                 if( cross_corr > 0 ) {
@@ -525,13 +562,14 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
         /* Save Lags */
         for( k = 0; k < nb_subfr; k++ ) {
             pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
-            pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 );
+            pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 );
         }
-        *lagIndex = (opus_int16)( lag - min_lag_8kHz );
+        *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
         *contourIndex = (opus_int8)CBimax;
     }
     silk_assert( *lagIndex >= 0 );
     /* return as voiced */
+    RESTORE_STACK;
     return 0;
 }
 
@@ -549,7 +587,7 @@ opus_int silk_pitch_analysis_core(                  /* O    Voicing estimate: 0
  * case 4*12*5 = 240 correlations, but more likely around 120.
  ***********************************************************************/
 static void silk_P_Ana_calc_corr_st3(
-    opus_int32        cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* O 3 DIM correlation array */
+    silk_pe_stage3_vals cross_corr_st3[],              /* O 3 DIM correlation array */
     const opus_int16  frame[],                         /* I vector to correlate         */
     opus_int          start_lag,                       /* I lag offset to search around */
     opus_int          sf_length,                       /* I length of a 5 ms subframe   */
@@ -561,8 +599,9 @@ static void silk_P_Ana_calc_corr_st3(
     opus_int32 cross_corr;
     opus_int   i, j, k, lag_counter, lag_low, lag_high;
     opus_int   nb_cbk_search, delta, idx, cbk_size;
-    opus_int32 scratch_mem[ SCRATCH_SIZE ];
+    VARDECL( opus_int32, scratch_mem );
     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 );
@@ -579,6 +618,7 @@ static void silk_P_Ana_calc_corr_st3(
         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
         cbk_size      = PE_NB_CBKS_STAGE3_10MS;
     }
+    ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
 
     target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
     for( k = 0; k < nb_subfr; k++ ) {
@@ -603,11 +643,13 @@ static void silk_P_Ana_calc_corr_st3(
             for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
                 silk_assert( idx + j < SCRATCH_SIZE );
                 silk_assert( idx + j < lag_counter );
-                cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
+                matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] =
+                    scratch_mem[ idx + j ];
             }
         }
         target_ptr += sf_length;
     }
+    RESTORE_STACK;
 }
 
 /********************************************************************/
@@ -615,7 +657,7 @@ static void silk_P_Ana_calc_corr_st3(
 /* calculated recursively.                                          */
 /********************************************************************/
 static void silk_P_Ana_calc_energy_st3(
-    opus_int32        energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],    /* O 3 DIM energy array */
+    silk_pe_stage3_vals energies_st3[],                 /* O 3 DIM energy array */
     const opus_int16  frame[],                          /* I vector to calc energy in    */
     opus_int          start_lag,                        /* I lag offset to search around */
     opus_int          sf_length,                        /* I length of one 5 ms subframe */
@@ -627,8 +669,9 @@ static void silk_P_Ana_calc_energy_st3(
     opus_int32 energy;
     opus_int   k, i, j, lag_counter;
     opus_int   nb_cbk_search, delta, idx, cbk_size, lag_diff;
-    opus_int32 scratch_mem[ SCRATCH_SIZE ];
+    VARDECL( opus_int32, scratch_mem );
     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 );
@@ -645,6 +688,8 @@ static void silk_P_Ana_calc_energy_st3(
         nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
         cbk_size      = PE_NB_CBKS_STAGE3_10MS;
     }
+    ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
+
     target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
     for( k = 0; k < nb_subfr; k++ ) {
         lag_counter = 0;
@@ -678,10 +723,13 @@ static void silk_P_Ana_calc_energy_st3(
             for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
                 silk_assert( idx + j < SCRATCH_SIZE );
                 silk_assert( idx + j < lag_counter );
-                energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
-                silk_assert( energies_st3[ k ][ i ][ j ] >= 0 );
+                matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] =
+                    scratch_mem[ idx + j ];
+                silk_assert(
+                    matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 );
             }
         }
         target_ptr += sf_length;
     }
+    RESTORE_STACK;
 }
diff --git a/silk/fixed/prefilter_FIX.c b/silk/fixed/prefilter_FIX.c
index a96f5118b0bd30681afccb9e3f0de69298fef181..ee559ffe2889118946849b14dd2ae074bf7f55e5 100644
--- a/silk/fixed/prefilter_FIX.c
+++ b/silk/fixed/prefilter_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 
 /* Prefilter for finding Quantizer input signal */
@@ -101,14 +102,17 @@ void silk_prefilter_FIX(
     opus_int32 *pxw_Q3;
     opus_int   HarmShapeGain_Q12, Tilt_Q14;
     opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
-    opus_int32 x_filt_Q12[ MAX_SUB_FRAME_LENGTH ];
-    opus_int32 st_res_Q2[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
+    VARDECL( opus_int32, x_filt_Q12 );
+    VARDECL( opus_int32, st_res_Q2 );
     opus_int16 B_Q10[ 2 ];
+    SAVE_STACK;
 
     /* Set up pointers */
     px  = x;
     pxw_Q3 = xw_Q3;
     lag = P->lagPrev;
+    ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 );
+    ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 );
     for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
         /* Update Variables that change per sub frame */
         if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
@@ -148,6 +152,7 @@ void silk_prefilter_FIX(
     }
 
     P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
+    RESTORE_STACK;
 }
 
 /* Prefilter for finding Quantizer input signal */
diff --git a/silk/fixed/residual_energy_FIX.c b/silk/fixed/residual_energy_FIX.c
index f284e51f0fe36b13034772beefdd0b7578fd2557..31c8fc62302ce5929a6ea06440271bc6b91d1931 100644
--- a/silk/fixed/residual_energy_FIX.c
+++ b/silk/fixed/residual_energy_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 
 /* Calculates residual energies of input subframes where all subframes have LPC_order   */
 /* of preceding samples                                                                 */
@@ -45,14 +46,18 @@ void silk_residual_energy_FIX(
 )
 {
     opus_int         offset, i, j, rshift, lz1, lz2;
-    opus_int16       *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
+    opus_int16       *LPC_res_ptr;
+    VARDECL( opus_int16, LPC_res );
     const opus_int16 *x_ptr;
     opus_int32       tmp32;
+    SAVE_STACK;
 
     x_ptr  = x;
     offset = LPC_order + subfr_length;
 
     /* 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 );
     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 );
@@ -88,4 +93,5 @@ void silk_residual_energy_FIX(
         nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/
         nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;
     }
+    RESTORE_STACK;
 }
diff --git a/silk/fixed/solve_LS_FIX.c b/silk/fixed/solve_LS_FIX.c
index fb913abeeba65b5d0b38e88d188d65ef5915c344..54b1c4ab8bad3e095fa3686eb7b06afac0e13251 100644
--- a/silk/fixed/solve_LS_FIX.c
+++ b/silk/fixed/solve_LS_FIX.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main_FIX.h"
+#include "stack_alloc.h"
 #include "tuning_parameters.h"
 
 /*****************************/
@@ -79,11 +80,13 @@ void silk_solve_LDL_FIX(
     opus_int32                      *x_Q16                                  /* O    Pointer to x solution vector                                                */
 )
 {
-    opus_int32 L_Q16[  MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ];
+    VARDECL( opus_int32, L_Q16 );
     opus_int32 Y[      MAX_MATRIX_SIZE ];
     inv_D_t   inv_D[  MAX_MATRIX_SIZE ];
+    SAVE_STACK;
 
     silk_assert( M <= MAX_MATRIX_SIZE );
+    ALLOC( L_Q16, M * M, opus_int32 );
 
     /***************************************************
     Factorize A by LDL such that A = L*D*L',
@@ -107,6 +110,7 @@ void silk_solve_LDL_FIX(
     x = inv(L') * inv(D) * Y
     *****************************************************/
     silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 );
+    RESTORE_STACK;
 }
 
 static inline void silk_LDL_factorize_FIX(
diff --git a/silk/macros.h b/silk/macros.h
index 2612fc7a418a21e86c4ddc2e8b776e2dc72a6eaa..31344cf4ba6d1f7643513fca31a8c07a1758f23a 100644
--- a/silk/macros.h
+++ b/silk/macros.h
@@ -123,12 +123,15 @@ static inline opus_int32 silk_CLZ32(opus_int32 in32)
 }
 
 /* Row based */
-#define matrix_ptr(Matrix_base_adr, row, column, N)         *(Matrix_base_adr + ((row)*(N)+(column)))
-#define matrix_adr(Matrix_base_adr, row, column, N)          (Matrix_base_adr + ((row)*(N)+(column)))
+#define matrix_ptr(Matrix_base_adr, row, column, N) \
+    (*((Matrix_base_adr) + ((row)*(N)+(column))))
+#define matrix_adr(Matrix_base_adr, row, column, N) \
+      ((Matrix_base_adr) + ((row)*(N)+(column)))
 
 /* Column based */
 #ifndef matrix_c_ptr
-#   define matrix_c_ptr(Matrix_base_adr, row, column, M)    *(Matrix_base_adr + ((row)+(M)*(column)))
+#   define matrix_c_ptr(Matrix_base_adr, row, column, M) \
+    (*((Matrix_base_adr) + ((row)+(M)*(column))))
 #endif
 
 #endif /* SILK_MACROS_H */
diff --git a/silk/resampler_down2.c b/silk/resampler_down2.c
index 21d11992696731050212223f260820d8cba73c64..0d5cd201e6ce4f35e126782e0c5eea40ee4e2fca 100644
--- a/silk/resampler_down2.c
+++ b/silk/resampler_down2.c
@@ -35,8 +35,8 @@ POSSIBILITY OF SUCH DAMAGE.
 /* Downsample by a factor 2 */
 void silk_resampler_down2(
     opus_int32                  *S,                 /* I/O  State vector [ 2 ]                                          */
-    opus_int16                  *out,               /* O    Output signal [ len ]                                       */
-    const opus_int16            *in,                /* I    Input signal [ floor(len/2) ]                               */
+    opus_int16                  *out,               /* O    Output signal [ floor(len/2) ]                              */
+    const opus_int16            *in,                /* I    Input signal [ len ]                                        */
     opus_int32                  inLen               /* I    Number of input samples                                     */
 )
 {
diff --git a/silk/resampler_down2_3.c b/silk/resampler_down2_3.c
index fe5b671d2bd611ac7cdd513ff056478646a51b96..709b86fc4ab2234da3a002d7004a22d352f98564 100644
--- a/silk/resampler_down2_3.c
+++ b/silk/resampler_down2_3.c
@@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
 
 #include "SigProc_FIX.h"
 #include "resampler_private.h"
+#include "stack_alloc.h"
 
 #define ORDER_FIR                   4
 
@@ -43,8 +44,11 @@ void silk_resampler_down2_3(
 )
 {
     opus_int32 nSamplesIn, counter, res_Q6;
-    opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ];
+    VARDECL( opus_int32, buf );
     opus_int32 *buf_ptr;
+    SAVE_STACK;
+
+    ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 );
 
     /* Copy buffered samples to start of buffer */
     silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) );
@@ -95,4 +99,5 @@ void silk_resampler_down2_3(
 
     /* Copy last part of filtered signal to the state for the next call */
     silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
+    RESTORE_STACK;
 }
diff --git a/silk/resampler_private_down_FIR.c b/silk/resampler_private_down_FIR.c
index 8bedb0de82b6e3561b2765b0048e783f82f9c9a3..a47582a6d323ad02b7be951f5e73065e24c93a07 100644
--- a/silk/resampler_private_down_FIR.c
+++ b/silk/resampler_private_down_FIR.c
@@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
 
 #include "SigProc_FIX.h"
 #include "resampler_private.h"
+#include "stack_alloc.h"
 
 static inline opus_int16 *silk_resampler_private_down_FIR_INTERPOL(
     opus_int16          *out,
@@ -151,8 +152,11 @@ void silk_resampler_private_down_FIR(
     silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS;
     opus_int32 nSamplesIn;
     opus_int32 max_index_Q16, index_increment_Q16;
-    opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + SILK_RESAMPLER_MAX_FIR_ORDER ];
+    VARDECL( opus_int32, buf );
     const opus_int16 *FIR_Coefs;
+    SAVE_STACK;
+
+    ALLOC( buf, S->batchSize + S->FIR_Order, opus_int32 );
 
     /* Copy buffered samples to start of buffer */
     silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) );
@@ -186,4 +190,5 @@ void silk_resampler_private_down_FIR(
 
     /* Copy last part of filtered signal to the state for the next call */
     silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) );
+    RESTORE_STACK;
 }
diff --git a/silk/stereo_LR_to_MS.c b/silk/stereo_LR_to_MS.c
index 6a680e09ff3b696c31b94f993d78aa8599e3e856..29204b63bfb7c506ddd5ab4b28b393fabf3b8e30 100644
--- a/silk/stereo_LR_to_MS.c
+++ b/silk/stereo_LR_to_MS.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 #include "main.h"
+#include "stack_alloc.h"
 
 /* Convert Left/Right stereo signal to adaptive Mid/Side representation */
 void silk_stereo_LR_to_MS(
@@ -49,11 +50,15 @@ void silk_stereo_LR_to_MS(
     opus_int   n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13;
     opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13;
     opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24;
-    opus_int16 side[ MAX_FRAME_LENGTH + 2 ];
-    opus_int16 LP_mid[  MAX_FRAME_LENGTH ], HP_mid[  MAX_FRAME_LENGTH ];
-    opus_int16 LP_side[ MAX_FRAME_LENGTH ], HP_side[ MAX_FRAME_LENGTH ];
+    VARDECL( opus_int16, side );
+    VARDECL( opus_int16, LP_mid );
+    VARDECL( opus_int16, HP_mid );
+    VARDECL( opus_int16, LP_side );
+    VARDECL( opus_int16, HP_side );
     opus_int16 *mid = &x1[ -2 ];
+    SAVE_STACK;
 
+    ALLOC( side, frame_length + 2, opus_int16 );
     /* Convert to basic mid/side signals */
     for( n = 0; n < frame_length + 2; n++ ) {
         sum  = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ];
@@ -69,6 +74,8 @@ void silk_stereo_LR_to_MS(
     silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) );
 
     /* LP and HP filter mid signal */
+    ALLOC( LP_mid, frame_length, opus_int16 );
+    ALLOC( HP_mid, frame_length, opus_int16 );
     for( n = 0; n < frame_length; n++ ) {
         sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );
         LP_mid[ n ] = sum;
@@ -76,6 +83,8 @@ void silk_stereo_LR_to_MS(
     }
 
     /* LP and HP filter side signal */
+    ALLOC( LP_side, frame_length, opus_int16 );
+    ALLOC( HP_side, frame_length, opus_int16 );
     for( n = 0; n < frame_length; n++ ) {
         sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 );
         LP_side[ n ] = sum;
@@ -216,4 +225,5 @@ void silk_stereo_LR_to_MS(
     state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];
     state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ];
     state->width_prev_Q14     = (opus_int16)width_Q14;
+    RESTORE_STACK;
 }
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 88bf5aff8217d836f300a64a5b2f7a5095e5a0ab..29ac96796f9f8a857b9c0d0a96be2a75df48f545 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -1241,7 +1241,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
        VARDECL(unsigned char, tmp_data);
        int nb_frames;
        int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
-       OpusRepacketizer rp;
+       VARDECL(OpusRepacketizer, rp);
        opus_int32 bytes_per_frame;
 
 
@@ -1250,7 +1250,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
 
        ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
 
-       opus_repacketizer_init(&rp);
+       ALLOC(rp, 1, OpusRepacketizer);
+       opus_repacketizer_init(rp);
 
        bak_mode = st->user_forced_mode;
        bak_bandwidth = st->user_bandwidth;
@@ -1282,14 +1283,14 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
              RESTORE_STACK;
              return OPUS_INTERNAL_ERROR;
           }
-          ret = opus_repacketizer_cat(&rp, tmp_data+i*bytes_per_frame, tmp_len);
+          ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
           if (ret<0)
           {
              RESTORE_STACK;
              return OPUS_INTERNAL_ERROR;
           }
        }
-       ret = opus_repacketizer_out(&rp, data, out_data_bytes);
+       ret = opus_repacketizer_out(rp, data, out_data_bytes);
        if (ret<0)
        {
           RESTORE_STACK;