diff --git a/autogen.sh b/autogen.sh
index 559067b0ca73db0e31bc6f86d142a6019f3394e8..f87f41228518181e4098edf32de19d00ed2f4253 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -9,7 +9,7 @@ set -e
 srcdir=`dirname $0`
 test -n "$srcdir" && cd "$srcdir"
 
-dnn/download_model.sh eb72d29
+dnn/download_model.sh ad05730
 
 echo "Updating build configuration files, please wait...."
 
diff --git a/dnn/dred_rdovae_dec.c b/dnn/dred_rdovae_dec.c
index 7e4b2ca9a539ad33194ccf0b96d06ec579649889..c79723b35148587c2e025ffbc31954dfe1e85173 100644
--- a/dnn/dred_rdovae_dec.c
+++ b/dnn/dred_rdovae_dec.c
@@ -40,9 +40,9 @@ void dred_rdovae_dec_init_states(
     )
 {
     /* initialize GRU states from initial state */
-    _lpcnet_compute_dense(&model->state1, h->dense2_state, initial_state);
-    _lpcnet_compute_dense(&model->state2, h->dense4_state, initial_state);
-    _lpcnet_compute_dense(&model->state3, h->dense6_state, initial_state);
+    compute_generic_dense(&model->state1, h->dense2_state, initial_state, ACTIVATION_TANH);
+    compute_generic_dense(&model->state2, h->dense4_state, initial_state, ACTIVATION_TANH);
+    compute_generic_dense(&model->state3, h->dense6_state, initial_state, ACTIVATION_TANH);
 }
 
 
@@ -56,42 +56,41 @@ void dred_rdovae_decode_qframe(
     float buffer[DEC_DENSE1_OUT_SIZE + DEC_DENSE2_OUT_SIZE + DEC_DENSE3_OUT_SIZE + DEC_DENSE4_OUT_SIZE + DEC_DENSE5_OUT_SIZE + DEC_DENSE6_OUT_SIZE + DEC_DENSE7_OUT_SIZE + DEC_DENSE8_OUT_SIZE];
     int output_index = 0;
     int input_index = 0;
-    float zero_vector[1024] = {0};
 
     /* run encoder stack and concatenate output in buffer*/
-    _lpcnet_compute_dense(&model->dec_dense1, &buffer[output_index], input);
+    compute_generic_dense(&model->dec_dense1, &buffer[output_index], input, ACTIVATION_TANH);
     input_index = output_index;
     output_index += DEC_DENSE1_OUT_SIZE;
 
-    compute_gruB(&model->dec_dense2, zero_vector, dec_state->dense2_state, &buffer[input_index]);
+    compute_generic_gru(&model->dec_dense2_input, &model->dec_dense2_recurrent, dec_state->dense2_state, &buffer[input_index]);
     OPUS_COPY(&buffer[output_index], dec_state->dense2_state, DEC_DENSE2_OUT_SIZE);
     input_index = output_index;
     output_index += DEC_DENSE2_OUT_SIZE;
 
-    _lpcnet_compute_dense(&model->dec_dense3, &buffer[output_index], &buffer[input_index]);
+    compute_generic_dense(&model->dec_dense3, &buffer[output_index], &buffer[input_index], ACTIVATION_TANH);
     input_index = output_index;
     output_index += DEC_DENSE3_OUT_SIZE;
 
-    compute_gruB(&model->dec_dense4, zero_vector, dec_state->dense4_state, &buffer[input_index]);
+    compute_generic_gru(&model->dec_dense4_input, &model->dec_dense4_recurrent, dec_state->dense4_state, &buffer[input_index]);
     OPUS_COPY(&buffer[output_index], dec_state->dense4_state, DEC_DENSE4_OUT_SIZE);
     input_index = output_index;
     output_index += DEC_DENSE4_OUT_SIZE;
 
-    _lpcnet_compute_dense(&model->dec_dense5, &buffer[output_index], &buffer[input_index]);
+    compute_generic_dense(&model->dec_dense5, &buffer[output_index], &buffer[input_index], ACTIVATION_TANH);
     input_index = output_index;
     output_index += DEC_DENSE5_OUT_SIZE;
 
-    compute_gruB(&model->dec_dense6, zero_vector, dec_state->dense6_state, &buffer[input_index]);
+    compute_generic_gru(&model->dec_dense6_input, &model->dec_dense6_recurrent, dec_state->dense6_state, &buffer[input_index]);
     OPUS_COPY(&buffer[output_index], dec_state->dense6_state, DEC_DENSE6_OUT_SIZE);
     input_index = output_index;
     output_index += DEC_DENSE6_OUT_SIZE;
 
-    _lpcnet_compute_dense(&model->dec_dense7, &buffer[output_index], &buffer[input_index]);
+    compute_generic_dense(&model->dec_dense7, &buffer[output_index], &buffer[input_index], ACTIVATION_TANH);
     input_index = output_index;
     output_index += DEC_DENSE7_OUT_SIZE;
 
-    _lpcnet_compute_dense(&model->dec_dense8, &buffer[output_index], &buffer[input_index]);
+    compute_generic_dense(&model->dec_dense8, &buffer[output_index], &buffer[input_index], ACTIVATION_TANH);
     output_index += DEC_DENSE8_OUT_SIZE;
 
-    _lpcnet_compute_dense(&model->dec_final, qframe, buffer);
+    compute_generic_dense(&model->dec_final, qframe, buffer, ACTIVATION_LINEAR);
 }
diff --git a/dnn/nnet.h b/dnn/nnet.h
index 0e7cd6dc3499f72c5303c216e90fbf789ee7517e..2916b33f7f01a0bea162f8ab80cbb16075acbb74 100644
--- a/dnn/nnet.h
+++ b/dnn/nnet.h
@@ -162,7 +162,7 @@ int sample_from_pdf(const float *pdf, int N, float exp_boost, float pdf_floor);
 extern const WeightArray lpcnet_arrays[];
 extern const WeightArray lpcnet_plc_arrays[];
 extern const WeightArray rdovaeenc_arrays[];
-extern const WeightArray rdovae_dec_arrays[];
+extern const WeightArray rdovaedec_arrays[];
 
 int linear_init(LinearLayer *layer, const WeightArray *arrays,
   const char *bias,
diff --git a/dnn/write_lpcnet_weights.c b/dnn/write_lpcnet_weights.c
index aa36db1f6c94e11cf517f804520d40f51a395ce0..3f6463d6bf1361a9fda2732bea9aee2772f3c8bf 100644
--- a/dnn/write_lpcnet_weights.c
+++ b/dnn/write_lpcnet_weights.c
@@ -73,7 +73,7 @@ int main(void)
   write_weights(lpcnet_arrays, fout);
   write_weights(lpcnet_plc_arrays, fout);
   write_weights(rdovaeenc_arrays, fout);
-  write_weights(rdovae_dec_arrays, fout);
+  write_weights(rdovaedec_arrays, fout);
   fclose(fout);
   return 0;
 }
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 45978d2a9957904cbc68011716195aca14a84ab8..e430ce82ad9cf3563a3c4ff1543b91f7b26db7e9 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -1165,7 +1165,7 @@ int dred_decoder_load_model(OpusDREDDecoder *dec, const unsigned char *data, int
 int opus_dred_decoder_init(OpusDREDDecoder *dec)
 {
 #if defined(ENABLE_NEURAL_FEC) && !defined(USE_WEIGHTS_FILE)
-   init_rdovaedec(&dec->model, rdovae_dec_arrays);
+   init_rdovaedec(&dec->model, rdovaedec_arrays);
 #endif
    dec->arch = opus_select_arch();
    /* To make sure nobody forgets to init, use a magic number. */