shithub: opus

Download patch

ref: 1978cc609408ecb004f7f61560694d2788aa1a26
parent: d1646a680a3c9e8a29261cac792d90f7c62101e1
author: Jan Buethe <jbuethe@amazon.de>
date: Fri Oct 21 08:13:38 EDT 2022

refactoring

--- /dev/null
+++ b/dnn/dred_rdovae_dec.c
@@ -1,0 +1,105 @@
+#include "dred_rdovae_dec.h"
+#include "dred_rdovae_constants.h"
+//#define DEBUG
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void dred_rdovae_dec_init_states(
+    RDOVAEDec *h,            /* io: state buffer handle */
+    const float *initial_state  /* i: initial state */
+    )
+{
+    /* initialize GRU states from initial state */
+    compute_dense(&state1, h->dense2_state, initial_state);
+    compute_dense(&state2, h->dense4_state, initial_state);
+    compute_dense(&state3, h->dense6_state, initial_state);
+}
+
+
+void dred_rdovae_decode_qframe(
+    RDOVAEDec *dec_state,       /* io: state buffer handle */
+    float *qframe,              /* o: quadruple feature frame (four concatenated frames) */
+    const float *input          /* i: latent vector */
+    )
+{
+    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;
+#ifdef DEBUG
+    static FILE *fids[8] = {NULL};
+    int i;
+    char filename[256];
+
+    for (i=0; i < 8; i ++)
+    {
+        if (fids[i] == NULL)
+        {
+            sprintf(filename, "y%d.f32", i + 1);
+            fids[i] = fopen(filename, "wb");
+        }
+    }
+#endif
+
+    /* run encoder stack and concatenate output in buffer*/
+    compute_dense(&dec_dense1, &buffer[output_index], input);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE1_OUT_SIZE, fids[0]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE1_OUT_SIZE;
+
+    compute_gru2(&dec_dense2, dec_state->dense2_state, &buffer[input_index]);
+    memcpy(&buffer[output_index], dec_state->dense2_state, DEC_DENSE2_OUT_SIZE * sizeof(float));
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE2_OUT_SIZE, fids[1]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE2_OUT_SIZE;
+
+    compute_dense(&dec_dense3, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE3_OUT_SIZE, fids[2]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE3_OUT_SIZE;
+
+    compute_gru2(&dec_dense4, dec_state->dense4_state, &buffer[input_index]);
+    memcpy(&buffer[output_index], dec_state->dense4_state, DEC_DENSE4_OUT_SIZE * sizeof(float));
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE4_OUT_SIZE, fids[3]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE4_OUT_SIZE;
+
+    compute_dense(&dec_dense5, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE5_OUT_SIZE, fids[4]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE5_OUT_SIZE;
+
+    compute_gru2(&dec_dense6, dec_state->dense6_state, &buffer[input_index]);
+    memcpy(&buffer[output_index], dec_state->dense6_state, DEC_DENSE6_OUT_SIZE * sizeof(float));
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE6_OUT_SIZE, fids[5]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE6_OUT_SIZE;
+
+    compute_dense(&dec_dense7, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE7_OUT_SIZE, fids[6]);
+#endif
+    input_index = output_index;
+    output_index += DEC_DENSE7_OUT_SIZE;
+
+    compute_dense(&dec_dense8, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE8_OUT_SIZE, fids[7]);
+#endif
+    output_index += DEC_DENSE8_OUT_SIZE;
+
+    compute_dense(&dec_final, qframe, buffer);
+}
\ No newline at end of file
--- /dev/null
+++ b/dnn/dred_rdovae_dec.h
@@ -1,0 +1,16 @@
+#ifndef _DRED_RDOVAE_DEC_H
+#define _DRED_RDOVAE_DEC_H
+
+#include "dred_rdovae_dec_data.h"
+#include "dred_rdovae_stats_data.h"
+
+typedef struct {
+    float dense2_state[DEC_DENSE2_STATE_SIZE];
+    float dense4_state[DEC_DENSE2_STATE_SIZE];
+    float dense6_state[DEC_DENSE2_STATE_SIZE];
+} RDOVAEDec;
+
+void dred_rdovae_dec_init_states(RDOVAEDec *h, const float * initial_state);
+void dred_rdovae_decode_qframe(RDOVAEDec *h, float *qframe, const float * z);
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/dnn/dred_rdovae_dec_demo.c
@@ -1,0 +1,66 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "dred_rdovae_dec.h"
+
+
+void usage()
+{
+    printf("dred_rdovae_dec_demo <input> <output>\n");
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    RDOVAEDec dec_state;
+    float feature_buffer[36];
+    float qframe[4 * DRED_NUM_FEATURES];
+    float latents[DRED_LATENT_DIM];
+    float initial_state[24];
+    int index = 0;
+    FILE *in_fid, *out_fid;
+    int qlevel = 0;
+
+    memset(&dec_state, 0, sizeof(dec_state));
+
+    if (argc < 3) usage();
+
+    in_fid = fopen(argv[1], "rb");
+    if (in_fid == NULL)
+    {
+        perror("Could not open input file");
+        usage();
+    }
+
+    out_fid = fopen(argv[2], "wb");
+    if (out_fid == NULL)
+    {
+        perror("Could not open output file");
+        usage();
+    }
+
+    /* read initial state from input stream */
+    if (fread(initial_state, sizeof(float), 24, in_fid) != 24)
+    {
+        perror("error while reading initial state");
+        return 1;
+    }
+
+    /* initialize GRU states */
+    dred_rdovae_dec_init_states(&dec_state, initial_state);
+
+    /* start decoding */
+    while (fread(latents, sizeof(float), 80, in_fid) == 80)
+    {
+        dred_rdovae_decode_qframe(&dec_state, qframe, latents);
+        fwrite(qframe, sizeof(float), 4*20, out_fid);
+    }
+
+    fclose(in_fid);
+    fclose(out_fid);
+
+
+    return 0;
+}
+
+/* gcc -DDISABLE_DOT_PROD -DDISABLE_NEON dred_rdovae_dec_demo.c dred_rdovae_dec.c nnet.c dred_rdovae_dec_data.c dred_rdovae_stats_data.c kiss99.c -g -o dred_rdovae_dec_demo */
\ No newline at end of file
--- /dev/null
+++ b/dnn/dred_rdovae_enc.c
@@ -1,0 +1,114 @@
+#include <math.h>
+
+#include "dred_rdovae_enc.h"
+
+
+//#define DEBUG
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void dred_rdovae_encode_dframe(
+    RDOVAEEnc *enc_state,           /* io: encoder state */
+    float *latents,                 /* o: latent vector */
+    float *initial_state,           /* o: initial state */
+    const float *input              /* i: double feature frame (concatenated) */
+    )
+{
+    float buffer[ENC_DENSE1_OUT_SIZE + ENC_DENSE2_OUT_SIZE + ENC_DENSE3_OUT_SIZE + ENC_DENSE4_OUT_SIZE + ENC_DENSE5_OUT_SIZE + ENC_DENSE6_OUT_SIZE + ENC_DENSE7_OUT_SIZE + ENC_DENSE8_OUT_SIZE + GDENSE1_OUT_SIZE];
+    int output_index = 0;
+    int input_index = 0;
+#ifdef DEBUG
+    static FILE *fids[8] = {NULL};
+    static FILE *fpre = NULL;
+    int i;
+    char filename[256];
+
+    for (i=0; i < 8; i ++)
+    {
+        if (fids[i] == NULL)
+        {
+            sprintf(filename, "x%d.f32", i + 1);
+            fids[i] = fopen(filename, "wb");
+        }
+    }
+    if (fpre == NULL)
+    {
+        fpre = fopen("x_pre.f32", "wb");
+    }
+#endif
+
+
+    /* run encoder stack and concatenate output in buffer*/
+    compute_dense(&enc_dense1, &buffer[output_index], input);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE1_OUT_SIZE, fids[0]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE1_OUT_SIZE;
+
+    compute_gru2(&enc_dense2, enc_state->dense2_state, &buffer[input_index]);
+    memcpy(&buffer[output_index], enc_state->dense2_state, ENC_DENSE2_OUT_SIZE * sizeof(float));
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE2_OUT_SIZE, fids[1]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE2_OUT_SIZE;
+
+    compute_dense(&enc_dense3, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE3_OUT_SIZE, fids[2]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE3_OUT_SIZE;
+
+    compute_gru2(&enc_dense4, enc_state->dense4_state, &buffer[input_index]);
+    memcpy(&buffer[output_index], enc_state->dense4_state, ENC_DENSE4_OUT_SIZE * sizeof(float));
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE4_OUT_SIZE, fids[3]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE4_OUT_SIZE;
+
+    compute_dense(&enc_dense5, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE5_OUT_SIZE, fids[4]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE5_OUT_SIZE;
+
+    compute_gru2(&enc_dense6, enc_state->dense6_state, &buffer[input_index]);
+    memcpy(&buffer[output_index], enc_state->dense6_state, ENC_DENSE6_OUT_SIZE * sizeof(float));
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE6_OUT_SIZE, fids[5]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE6_OUT_SIZE;
+
+    compute_dense(&enc_dense7, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE7_OUT_SIZE, fids[6]);
+#endif
+    input_index = output_index;
+    output_index += ENC_DENSE7_OUT_SIZE;
+
+    compute_dense(&enc_dense8, &buffer[output_index], &buffer[input_index]);
+#ifdef DEBUG
+    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE8_OUT_SIZE, fids[7]);
+#endif
+    output_index += ENC_DENSE8_OUT_SIZE;
+
+    /* compute latents from concatenated input buffer */
+#ifdef DEBUG
+    fwrite(buffer, sizeof(buffer[0]), bits_dense.nb_inputs, fpre);
+#endif
+    compute_conv1d(&bits_dense, latents, enc_state->bits_dense_state, buffer);
+
+
+    /* next, calculate initial state */
+    compute_dense(&gdense1, &buffer[output_index], buffer);
+    input_index = output_index;
+    compute_dense(&gdense2, initial_state, &buffer[input_index]);
+
+}
--- /dev/null
+++ b/dnn/dred_rdovae_enc.h
@@ -1,0 +1,16 @@
+#ifndef _DRED_RDOVAE_ENC_H
+#define _DRED_RDOVAE_ENC_H
+
+#include "dred_rdovae_enc_data.h"
+
+typedef struct {
+    float dense2_state[3 * ENC_DENSE2_STATE_SIZE];
+    float dense4_state[3 * ENC_DENSE4_STATE_SIZE];
+    float dense6_state[3 * ENC_DENSE6_STATE_SIZE];
+    float bits_dense_state[BITS_DENSE_STATE_SIZE];
+} RDOVAEEnc;
+
+void dred_rdovae_encode_dframe(RDOVAEEnc *enc_state, float *latents, float *initial_state, const float *input);
+
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/dnn/dred_rdovae_enc_demo.c
@@ -1,0 +1,72 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "dred_rdovae_enc.h"
+#include "dred_rdovae_constants.h"
+
+void usage()
+{
+    printf("dred_rdovae_enc_demo <features> <latents path> <states path>\n");
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    RDOVAEEnc enc_state;
+    float feature_buffer[36];
+    float dframe[2 * DRED_NUM_FEATURES];
+    float latents[80];
+    float initial_state[24];
+    int index = 0;
+    FILE *fid, *latents_fid, *states_fid;
+
+    memset(&enc_state, 0, sizeof(enc_state));
+
+    if (argc < 4)
+    {
+        usage();
+    }
+
+    fid = fopen(argv[1], "rb");
+    if (fid == NULL)
+    {
+        fprintf(stderr, "could not open feature file %s\n", argv[1]);
+        usage();
+    }
+
+    latents_fid = fopen(argv[2], "wb");
+    if (latents_fid == NULL)
+    {
+        fprintf(stderr, "could not open latents file %s\n", argv[2]);
+        usage();
+    }
+
+    states_fid = fopen(argv[3], "wb");
+    if (states_fid == NULL)
+    {
+        fprintf(stderr, "could not open states file %s\n", argv[3]);
+        usage();
+    }
+
+
+    while (fread(feature_buffer, sizeof(float), 36, fid) == 36)
+    {
+        memcpy(&dframe[DRED_NUM_FEATURES * index++], feature_buffer, DRED_NUM_FEATURES*sizeof(float));
+
+        if (index == 2)
+        {
+            dred_rdovae_encode_dframe(&enc_state, latents, initial_state, dframe);
+            index = 0;
+            fwrite(latents, sizeof(float), DRED_LATENT_DIM, latents_fid);
+            fwrite(initial_state, sizeof(float), GDENSE2_OUT_SIZE, states_fid);
+        }
+    }
+
+    fclose(fid);
+    fclose(states_fid);
+    fclose(latents_fid);
+
+    return 0;
+}
+
+/* gcc -DDISABLE_DOT_PROD -DDISABLE_NEON dred_rdovae_enc_demo.c dred_rdovae_enc.c nnet.c dred_rdovae_enc_data.c dred_rdovae_stats_data.c kiss99.c -g -o dred_rdovae_enc_demo */
\ No newline at end of file
--- a/dnn/nfec_dec.c
+++ /dev/null
@@ -1,118 +1,0 @@
-#include "nfec_dec.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-void nfec_dec_init_states(
-    NFECDecState *h,            /* io: state buffer handle */
-    const float *initial_state  /* i: initial state */
-    )
-{
-    /* initialize GRU states from initial state */
-    compute_dense(&state1, h->dense2_state, initial_state);
-    compute_dense(&state2, h->dense4_state, initial_state);
-    compute_dense(&state3, h->dense6_state, initial_state);
-}
-
-void nfec_dec_unquantize_latent_vector(
-    float *z,       /* o: unquantized latent vector */
-    const int *zq,  /* i: quantized latent vector */
-    int quant_level /* i: quantization level */
-    )
-{
-    int i;
-    /* inverse scaling and type conversion */
-    for (i = 0; i < NFEC_STATS_NUM_LATENTS; i ++)
-    {
-        z[i] = (float) zq[i] / nfec_stats_quant_scales[quant_level * NFEC_STATS_NUM_LATENTS + i];
-    }
-}
-
-void nfec_decode_qframe(
-    NFECDecState *dec_state,    /* io: state buffer handle */
-    float *qframe,              /* o: quadruple feature frame (four concatenated frames) */
-    const float *input          /* i: latent vector */
-    )
-{
-    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;
-#ifdef DEBUG
-    static FILE *fids[8] = {NULL};
-    int i;
-    char filename[256];
-
-    for (i=0; i < 8; i ++)
-    {
-        if (fids[i] == NULL)
-        {
-            sprintf(filename, "y%d.f32", i + 1);
-            fids[i] = fopen(filename, "wb");
-        }
-    }
-#endif
-
-    /* run encoder stack and concatenate output in buffer*/
-    compute_dense(&dec_dense1, &buffer[output_index], input);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE1_OUT_SIZE, fids[0]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE1_OUT_SIZE;
-
-    compute_gru2(&dec_dense2, dec_state->dense2_state, &buffer[input_index]);
-    memcpy(&buffer[output_index], dec_state->dense2_state, DEC_DENSE2_OUT_SIZE * sizeof(float));
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE2_OUT_SIZE, fids[1]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE2_OUT_SIZE;
-
-    compute_dense(&dec_dense3, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE3_OUT_SIZE, fids[2]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE3_OUT_SIZE;
-
-    compute_gru2(&dec_dense4, dec_state->dense4_state, &buffer[input_index]);
-    memcpy(&buffer[output_index], dec_state->dense4_state, DEC_DENSE4_OUT_SIZE * sizeof(float));
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE4_OUT_SIZE, fids[3]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE4_OUT_SIZE;
-
-    compute_dense(&dec_dense5, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE5_OUT_SIZE, fids[4]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE5_OUT_SIZE;
-
-    compute_gru2(&dec_dense6, dec_state->dense6_state, &buffer[input_index]);
-    memcpy(&buffer[output_index], dec_state->dense6_state, DEC_DENSE6_OUT_SIZE * sizeof(float));
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE6_OUT_SIZE, fids[5]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE6_OUT_SIZE;
-
-    compute_dense(&dec_dense7, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE7_OUT_SIZE, fids[6]);
-#endif
-    input_index = output_index;
-    output_index += DEC_DENSE7_OUT_SIZE;
-
-    compute_dense(&dec_dense8, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), DEC_DENSE8_OUT_SIZE, fids[7]);
-#endif
-    output_index += DEC_DENSE8_OUT_SIZE;
-
-    compute_dense(&dec_final, qframe, buffer);
-}
\ No newline at end of file
--- a/dnn/nfec_dec.h
+++ /dev/null
@@ -1,17 +1,0 @@
-#ifndef _NFEC_DEC_H
-#define _NFEC_DEC_H
-
-#include "nfec_dec_data.h"
-#include "nfec_stats_data.h"
-
-typedef struct {
-    float dense2_state[DEC_DENSE2_STATE_SIZE];
-    float dense4_state[DEC_DENSE2_STATE_SIZE];
-    float dense6_state[DEC_DENSE2_STATE_SIZE];
-} NFECDecState;
-
-void nfec_dec_init_states(NFECDecState *h, const float * initial_state);
-void nfec_dec_unquantize_latent_vector(float *z, const int *zq, int quant_level);
-void nfec_decode_qframe(NFECDecState *h, float *qframe, const float * z);
-
-#endif
\ No newline at end of file
--- a/dnn/nfec_dec_demo.c
+++ /dev/null
@@ -1,68 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "nfec_dec.h"
-#include "nfec_enc.h"
-
-
-void usage()
-{
-    printf("nfec_dec_demo <input> <output>\n");
-    exit(1);
-}
-
-int main(int argc, char **argv)
-{
-    NFECDecState dec_state;
-    float feature_buffer[36];
-    float qframe[4 * NFEC_DEC_NUM_FEATURES];
-    float latents[80];
-    float initial_state[24];
-    int quantized_latents[80];
-    int index = 0;
-    FILE *in_fid, *out_fid;
-    int qlevel = 0;
-
-    memset(&dec_state, 0, sizeof(dec_state));
-
-    if (argc < 3) usage();
-
-    in_fid = fopen(argv[1], "rb");
-    if (in_fid == NULL)
-    {
-        perror("Could not open input file");
-        usage();
-    }
-
-    out_fid = fopen(argv[2], "wb");
-    if (out_fid == NULL)
-    {
-        perror("Could not open output file");
-        usage();
-    }
-
-    /* read initial state from input stream */
-    if (fread(initial_state, sizeof(float), 24, in_fid) != 24)
-    {
-        perror("error while reading initial state");
-        return 1;
-    }
-
-    /* initialize GRU states */
-    nfec_dec_init_states(&dec_state, initial_state);
-
-    /* start decoding */
-    while (fread(latents, sizeof(float), 80, in_fid) == 80)
-    {
-        nfec_decode_qframe(&dec_state, qframe, latents);
-        fwrite(qframe, sizeof(float), 4*20, out_fid);
-    }
-
-    fclose(in_fid);
-    fclose(out_fid);
-
-
-    return 0;
-}
-
-/* gcc -DDISABLE_DOT_PROD -DDISABLE_NEON nfec_dec_demo.c nfec_dec.c nnet.c nfec_dec_data.c nfec_stats_data.c kiss99.c -g -o nfec_dec_demo */
\ No newline at end of file
--- a/dnn/nfec_enc.c
+++ /dev/null
@@ -1,140 +1,0 @@
-#include <math.h>
-
-#include "nfec_enc.h"
-#include "nnet.h"
-#include "nfec_enc_data.h"
-#include "nfec_stats_data.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-void nfec_encode_dframe(
-    struct NFECEncState *enc_state, /* io: encoder state */
-    float *latents,                 /* o: latent vector */
-    float *initial_state,           /* o: initial state */
-    const float *input              /* i: double feature frame (concatenated) */
-    )
-{
-    float buffer[ENC_DENSE1_OUT_SIZE + ENC_DENSE2_OUT_SIZE + ENC_DENSE3_OUT_SIZE + ENC_DENSE4_OUT_SIZE + ENC_DENSE5_OUT_SIZE + ENC_DENSE6_OUT_SIZE + ENC_DENSE7_OUT_SIZE + ENC_DENSE8_OUT_SIZE + GDENSE1_OUT_SIZE];
-    int output_index = 0;
-    int input_index = 0;
-#ifdef DEBUG
-    static FILE *fids[8] = {NULL};
-    static FILE *fpre = NULL;
-    int i;
-    char filename[256];
-
-    for (i=0; i < 8; i ++)
-    {
-        if (fids[i] == NULL)
-        {
-            sprintf(filename, "x%d.f32", i + 1);
-            fids[i] = fopen(filename, "wb");
-        }
-    }
-    if (fpre == NULL)
-    {
-        fpre = fopen("x_pre.f32", "wb");
-    }
-#endif
-
-
-    /* run encoder stack and concatenate output in buffer*/
-    compute_dense(&enc_dense1, &buffer[output_index], input);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE1_OUT_SIZE, fids[0]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE1_OUT_SIZE;
-
-    compute_gru2(&enc_dense2, enc_state->dense2_state, &buffer[input_index]);
-    memcpy(&buffer[output_index], enc_state->dense2_state, ENC_DENSE2_OUT_SIZE * sizeof(float));
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE2_OUT_SIZE, fids[1]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE2_OUT_SIZE;
-
-    compute_dense(&enc_dense3, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE3_OUT_SIZE, fids[2]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE3_OUT_SIZE;
-
-    compute_gru2(&enc_dense4, enc_state->dense4_state, &buffer[input_index]);
-    memcpy(&buffer[output_index], enc_state->dense4_state, ENC_DENSE4_OUT_SIZE * sizeof(float));
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE4_OUT_SIZE, fids[3]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE4_OUT_SIZE;
-
-    compute_dense(&enc_dense5, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE5_OUT_SIZE, fids[4]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE5_OUT_SIZE;
-
-    compute_gru2(&enc_dense6, enc_state->dense6_state, &buffer[input_index]);
-    memcpy(&buffer[output_index], enc_state->dense6_state, ENC_DENSE6_OUT_SIZE * sizeof(float));
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE6_OUT_SIZE, fids[5]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE6_OUT_SIZE;
-
-    compute_dense(&enc_dense7, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE7_OUT_SIZE, fids[6]);
-#endif
-    input_index = output_index;
-    output_index += ENC_DENSE7_OUT_SIZE;
-
-    compute_dense(&enc_dense8, &buffer[output_index], &buffer[input_index]);
-#ifdef DEBUG
-    fwrite(&buffer[output_index], sizeof(buffer[0]), ENC_DENSE8_OUT_SIZE, fids[7]);
-#endif
-    output_index += ENC_DENSE8_OUT_SIZE;
-
-    /* compute latents from concatenated input buffer */
-#ifdef DEBUG
-    fwrite(buffer, sizeof(buffer[0]), bits_dense.nb_inputs, fpre);
-#endif
-    compute_conv1d(&bits_dense, latents, enc_state->bits_dense_state, buffer);
-
-
-    /* next, calculate initial state */
-    compute_dense(&gdense1, &buffer[output_index], buffer);
-    input_index = output_index;
-    compute_dense(&gdense2, initial_state, &buffer[input_index]);
-
-}
-
-void nfec_quantize_latent_vector(
-    int *z_q,           /* o: quantized latent vector */
-    const float *z,     /* i: unquantized latent vector */
-    int quant_level     /* i: quantization level */
-    )
-{
-    int i;
-    float delta;
-    float tmp[NFEC_LATENT_DIM];
-
-    for (i = 0; i < NFEC_LATENT_DIM; i ++)
-    {
-        /* dead-zone transform */
-        delta = nfec_stats_dead_zone_theta[quant_level * NFEC_LATENT_DIM + i] - .5f;
-        tmp[i] = z[i] - delta * tanhf(z[i] / (delta + 0.1f));
-
-        /* scaling */
-        tmp[i] *= nfec_stats_quant_scales[quant_level * NFEC_LATENT_DIM + i];
-
-        /* quantization by rounding (CAVE: is there a quantization routine with overlfow check available?) */
-        z_q[i] = (int) roundf(tmp[i]);
-    }
-}
\ No newline at end of file
--- a/dnn/nfec_enc.h
+++ /dev/null
@@ -1,16 +1,0 @@
-#ifndef _NFEC_ENC_H
-#define _NFEC_ENC_H
-
-#include "nfec_enc_data.h"
-
-struct NFECEncState{
-    float dense2_state[3 * ENC_DENSE2_STATE_SIZE];
-    float dense4_state[3 * ENC_DENSE4_STATE_SIZE];
-    float dense6_state[3 * ENC_DENSE6_STATE_SIZE];
-    float bits_dense_state[BITS_DENSE_STATE_SIZE];
-};
-
-void nfec_encode_dframe(struct NFECEncState *enc_state, float *latents, float *initial_state, const float *input);
-void nfec_quantize_latent_vector(int *z_q, const float *z, int quant_level);
-
-#endif
\ No newline at end of file
--- a/dnn/nfec_enc_demo.c
+++ /dev/null
@@ -1,85 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "nfec_enc.h"
-
-void usage()
-{
-    printf("nfec_enc_demo <features> <latents path> <states path>\n");
-    exit(1);
-}
-
-int main(int argc, char **argv)
-{
-    struct NFECEncState enc_state;
-    float feature_buffer[36];
-    float dframe[2 * NFEC_NUM_FEATURES];
-    float latents[80];
-    float initial_state[24];
-    int quantized_latents[NFEC_LATENT_DIM];
-    int index = 0;
-    FILE *fid, *latents_fid, *quantized_latents_fid, *states_fid;
-
-    memset(&enc_state, 0, sizeof(enc_state));
-
-    if (argc < 4)
-    {
-        usage();
-    }
-
-    fid = fopen(argv[1], "rb");
-    if (fid == NULL)
-    {
-        fprintf(stderr, "could not open feature file %s\n", argv[1]);
-        usage();
-    }
-
-    latents_fid = fopen(argv[2], "wb");
-    if (latents_fid == NULL)
-    {
-        fprintf(stderr, "could not open latents file %s\n", argv[2]);
-        usage();
-    }
-
-    char filename[256];
-    strcpy(filename, argv[2]);
-    strcat(filename, ".quantized.f32");
-    quantized_latents_fid = fopen(filename, "wb");
-    if (latents_fid == NULL)
-    {
-        fprintf(stderr, "could not open latents file %s\n", filename);
-        usage();
-    }
-
-    states_fid = fopen(argv[3], "wb");
-    if (states_fid == NULL)
-    {
-        fprintf(stderr, "could not open states file %s\n", argv[3]);
-        usage();
-    }
-
-
-    while (fread(feature_buffer, sizeof(float), 36, fid) == 36)
-    {
-        memcpy(&dframe[NFEC_NUM_FEATURES * index++], feature_buffer, NFEC_NUM_FEATURES*sizeof(float));
-
-        if (index == 2)
-        {
-            nfec_encode_dframe(&enc_state, latents, initial_state, dframe);
-            nfec_quantize_latent_vector(quantized_latents, latents, 0);
-            index = 0;
-            fwrite(latents, sizeof(float), NFEC_LATENT_DIM, latents_fid);
-            fwrite(quantized_latents, sizeof(int), NFEC_LATENT_DIM, quantized_latents_fid);
-            fwrite(initial_state, sizeof(float), GDENSE2_OUT_SIZE, states_fid);
-        }
-    }
-
-    fclose(fid);
-    fclose(states_fid);
-    fclose(latents_fid);
-    fclose(quantized_latents_fid);
-
-    return 0;
-}
-
-/* gcc -DDISABLE_DOT_PROD -DDISABLE_NEON nfec_enc_demo.c nfec_enc.c nnet.c nfec_enc_data.c nfec_stats_data.c kiss99.c -g -o nfec_enc_demo */
\ No newline at end of file
--- a/dnn/nnet.c
+++ b/dnn/nnet.c
@@ -38,7 +38,7 @@
 #include "tansig_table.h"
 #include "nnet.h"
 #include "nnet_data.h"
-#include "nfec_enc_data.h"
+#include "dred_rdovae_constants.h"
 #include "plc_data.h"
 
 #ifdef NO_OPTIMIZATIONS
@@ -322,7 +322,7 @@
       state[i] = h[i];
 }
 
-#define MAX_RNN_NEURONS_ALL IMAX(IMAX(MAX_RNN_NEURONS, PLC_MAX_RNN_NEURONS), NFEC_ENC_MAX_RNN_NEURONS)
+#define MAX_RNN_NEURONS_ALL IMAX(IMAX(MAX_RNN_NEURONS, PLC_MAX_RNN_NEURONS), DRED_MAX_RNN_NEURONS)
 
 void compute_gruB(const GRULayer *gru, const float* gru_b_condition, float *state, const float *input)
 {
@@ -378,8 +378,8 @@
    int i;
    int N;
    int stride;
-   float zrh[3*MAX_RNN_NEURONS];
-   float recur[3*MAX_RNN_NEURONS];
+   float zrh[3*MAX_RNN_NEURONS_ALL];
+   float recur[3*MAX_RNN_NEURONS_ALL];
    float *z;
    float *r;
    float *h;
@@ -387,7 +387,7 @@
    z = zrh;
    r = &zrh[N];
    h = &zrh[2*N];
-   celt_assert(gru->nb_neurons <= MAX_RNN_NEURONS);
+   celt_assert(gru->nb_neurons <= MAX_RNN_NEURONS_ALL);
    celt_assert(input != state);
    celt_assert(gru->reset_after);
    stride = 3*N;
@@ -412,7 +412,7 @@
 {
    int i, k;
    int N;
-   float recur[3*MAX_RNN_NEURONS];
+   float recur[3*MAX_RNN_NEURONS_ALL];
    float *z;
    float *r;
    float *h;
@@ -421,7 +421,7 @@
    z = recur;
    r = &recur[N];
    h = &recur[2*N];
-   celt_assert(gru->nb_neurons <= MAX_RNN_NEURONS);
+   celt_assert(gru->nb_neurons <= MAX_RNN_NEURONS_ALL);
    celt_assert(input != state);
    celt_assert(gru->reset_after);
 #ifdef USE_SU_BIAS
@@ -448,7 +448,7 @@
       state[i] = z[i]*state[i] + (1-z[i])*h[i];
 }
 
-#define MAX_CONV_INPUTS_ALL IMAX(MAX_CONV_INPUTS, NFEC_ENC_MAX_CONV_INPUTS)
+#define MAX_CONV_INPUTS_ALL IMAX(MAX_CONV_INPUTS, DRED_MAX_CONV_INPUTS)
 
 void compute_conv1d(const Conv1DLayer *layer, float *output, float *mem, const float *input)
 {
@@ -457,7 +457,7 @@
    int stride;
    float tmp[MAX_CONV_INPUTS_ALL];
    celt_assert(input != output);
-   celt_assert(layer->nb_inputs*layer->kernel_size <= MAX_CONV_INPUTS);
+   celt_assert(layer->nb_inputs*layer->kernel_size <= MAX_CONV_INPUTS_ALL);
    RNN_COPY(tmp, mem, layer->nb_inputs*(layer->kernel_size-1));
    RNN_COPY(&tmp[layer->nb_inputs*(layer->kernel_size-1)], input, layer->nb_inputs);
    M = layer->nb_inputs*layer->kernel_size;
--- a/dnn/training_tf2/dump_nfec_model.py
+++ /dev/null
@@ -1,232 +1,0 @@
-import argparse
-import os
-
-os.environ['CUDA_VISIBLE_DEVICES'] = ""
-
-parser = argparse.ArgumentParser()
-
-parser.add_argument('weights', metavar="<weight file>", type=str, help='model weight file in hdf5 format')
-parser.add_argument('--cond-size', type=int, help="conditioning size (default: 256)", default=256)
-parser.add_argument('--latent-dim', type=int, help="dimension of latent space (default: 80)", default=80)
-
-args = parser.parse_args()
-
-# now import the heavy stuff
-import tensorflow as tf
-from keraslayerdump import dump_conv1d_layer, dump_dense_layer, dump_gru_layer, printVector
-from rdovae import new_rdovae_model
-
-def start_header(header_fid, header_name):
-    header_guard = "_" + os.path.basename(header_name)[:-2].upper() + "_H"
-    header_fid.write(
-f"""
-#ifndef {header_guard}
-#define {header_guard}
-
-#include "nnet.h"
-
-"""
-    )
-
-def finish_header(header_fid):
-    header_fid.write(
-"""
-#endif
-
-"""
-    )
-
-def start_source(source_fid, header_name, weight_file):
-    source_fid.write(
-f"""
-/* this source file was automatically generated from weight file {weight_file} */
-
-#include "{header_name}"
-
-"""
-    )
-
-def finish_source(source_fid):
-    pass
-
-
-def dump_statistical_model(qembedding, f, fh):
-    w = qembedding.weights[0].numpy()
-    levels, dim = w.shape
-    N = dim // 6
-
-    quant_scales    = tf.math.softplus(w[:, : N]).numpy()
-    dead_zone_theta = 0.5 + 0.05 * tf.math.softplus(w[:, N : 2 * N]).numpy()
-    r               = 0.5 + 0.5 * tf.math.sigmoid(w[:, 4 * N : 5 * N]).numpy()
-    theta           = tf.math.sigmoid(w[:, 5 * N : 6 * N]).numpy()
-
-    printVector(f, quant_scales[:], 'nfec_stats_quant_scales', static=False)
-    printVector(f, dead_zone_theta[:], 'nfec_stats_dead_zone_theta', static=False)
-    printVector(f, r, 'nfec_stats_r', static=False)
-    printVector(f, theta, 'nfec_stats_theta', static=False)
-
-    fh.write(
-f"""
-extern const float nfec_stats_quant_scales[{levels * N}];
-extern const float nfec_stats_dead_zone_theta[{levels * N}];
-extern const float nfec_stats_r[{levels * N}];
-extern const float nfec_stats_theta[{levels * N}];
-
-"""
-    )
-
-if __name__ == "__main__":
-
-    model, encoder, decoder, qembedding = new_rdovae_model(20, args.latent_dim, cond_size=args.cond_size)
-    model.load_weights(args.weights)
-
-
-    # encoder
-    encoder_dense_names = [
-        'enc_dense1',
-        'enc_dense3',
-        'enc_dense5',
-        'enc_dense7',
-        'enc_dense8',
-        'gdense1',
-        'gdense2'
-    ]
-
-    encoder_gru_names = [
-        'enc_dense2',
-        'enc_dense4',
-        'enc_dense6'
-    ]
-
-    encoder_conv1d_names = [
-        'bits_dense'
-    ]
-
-    source_fid = open("nfec_enc_data.c", 'w')
-    header_fid = open("nfec_enc_data.h", 'w')
-
-    start_header(header_fid, "nfec_enc_data.h")
-    start_source(source_fid, "nfec_enc_data.h", os.path.basename(args.weights))
-
-    # dump GRUs
-    max_rnn_neurons = max(
-        [
-            dump_gru_layer(encoder.get_layer(name), source_fid, header_fid)
-            for name in encoder_gru_names
-        ]
-    )
-
-    # dump conv layers
-    max_conv_inputs = max(
-        [
-            dump_conv1d_layer(encoder.get_layer(name), source_fid, header_fid)
-            for name in encoder_conv1d_names
-        ] 
-    )
-
-    # dump Dense layers
-    for name in encoder_dense_names:
-        layer = encoder.get_layer(name)
-        dump_dense_layer(layer, source_fid, header_fid)
-
-    # some global constants
-    header_fid.write(
-f"""
-#define NFEC_NUM_FEATURES 20
-
-#define NFEC_LATENT_DIM {args.latent_dim}
-
-#define NFEC_ENC_MAX_RNN_NEURONS {max_rnn_neurons}
-
-#define NFEC_ENC_MAX_CONV_INPUTS {max_conv_inputs}
-
-"""
-    )
-
-    finish_header(header_fid)
-    finish_source(source_fid)
-
-    header_fid.close()
-    source_fid.close()
-
-    # statistical model
-    source_fid = open("nfec_stats_data.c", 'w')
-    header_fid = open("nfec_stats_data.h", 'w')
-
-    start_header(header_fid, "nfec_stats_data.h")
-    start_source(source_fid, "nfec_stats_data.h", os.path.basename(args.weights))
-
-    num_levels = qembedding.weights[0].shape[0]
-    header_fid.write(
-f"""
-#define NFEC_STATS_NUM_LEVELS {num_levels}
-#define NFEC_STATS_NUM_LATENTS {args.latent_dim}
-
-"""
-    )
-
-    dump_statistical_model(qembedding, source_fid, header_fid)
-
-    finish_header(header_fid)
-    finish_source(source_fid)
-
-    header_fid.close()
-    source_fid.close()
-
-    # decoder
-    decoder_dense_names = [
-        'state1',
-        'state2',
-        'state3',
-        'dec_dense1',
-        'dec_dense3',
-        'dec_dense5',
-        'dec_dense7',
-        'dec_dense8',
-        'dec_final'
-    ]   
-
-    decoder_gru_names = [
-        'dec_dense2',
-        'dec_dense4',
-        'dec_dense6'
-    ] 
-
-    source_fid = open("nfec_dec_data.c", 'w')
-    header_fid = open("nfec_dec_data.h", 'w')
-
-    start_header(header_fid, "nfec_dec_data.h")
-    start_source(source_fid, "nfec_dec_data.h", os.path.basename(args.weights))
-
-    # some global constants
-    header_fid.write(
-f"""
-#define NFEC_DEC_NUM_FEATURES 20
-
-#define NFEC_DEC_LATENT_DIM {args.latent_dim}
-
-#define NFEC_DEC_MAX_RNN_NEURONS {max_rnn_neurons}
-
-
-"""
-    )
-
-
-    # dump GRUs
-    max_rnn_neurons = max(
-        [
-            dump_gru_layer(decoder.get_layer(name), source_fid, header_fid)
-            for name in decoder_gru_names
-        ]
-    )
-
-    # dump Dense layers
-    for name in decoder_dense_names:
-        layer = decoder.get_layer(name)
-        dump_dense_layer(layer, source_fid, header_fid)
-
-    finish_header(header_fid)
-    finish_source(source_fid)
-
-    header_fid.close()
-    source_fid.close()
\ No newline at end of file
--- /dev/null
+++ b/dnn/training_tf2/dump_rdovae.py
@@ -1,0 +1,259 @@
+import argparse
+from ftplib import parse150
+import os
+
+os.environ['CUDA_VISIBLE_DEVICES'] = ""
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument('weights', metavar="<weight file>", type=str, help='model weight file in hdf5 format')
+parser.add_argument('--cond-size', type=int, help="conditioning size (default: 256)", default=256)
+parser.add_argument('--latent-dim', type=int, help="dimension of latent space (default: 80)", default=80)
+
+args = parser.parse_args()
+
+# now import the heavy stuff
+import tensorflow as tf
+import numpy as np
+from keraslayerdump import dump_conv1d_layer, dump_dense_layer, dump_gru_layer, printVector
+from rdovae import new_rdovae_model
+
+def start_header(header_fid, header_name):
+    header_guard = "_" + os.path.basename(header_name)[:-2].upper() + "_H"
+    header_fid.write(
+f"""
+#ifndef {header_guard}
+#define {header_guard}
+
+#include "nnet.h"
+
+"""
+    )
+
+def finish_header(header_fid):
+    header_fid.write(
+"""
+#endif
+
+"""
+    )
+
+def start_source(source_fid, header_name, weight_file):
+    source_fid.write(
+f"""
+/* this source file was automatically generated from weight file {weight_file} */
+
+#include "{header_name}"
+
+"""
+    )
+
+def finish_source(source_fid):
+    pass
+
+
+def dump_statistical_model(qembedding, f, fh):
+    w = qembedding.weights[0].numpy()
+    levels, dim = w.shape
+    N = dim // 6
+
+    print("dumping statistical model")
+    quant_scales    = tf.math.softplus(w[:, : N]).numpy()
+    dead_zone       = 0.05 * tf.math.softplus(w[:, N : 2 * N]).numpy()
+    r               = 0.5 + 0.5 * tf.math.sigmoid(w[:, 4 * N : 5 * N]).numpy()
+    theta           = tf.math.sigmoid(w[:, 5 * N : 6 * N]).numpy()
+    p0              = 1 - r ** (0.5 + 0.5 * theta)
+
+    quant_scales_q8 = np.round(quant_scales * 2**8).astype(np.int16)
+    dead_zone_q10   = np.round(dead_zone * 2**10).astype(np.int16)
+    r_q15           = np.round(r * 2**15).astype(np.int16)
+    p0_q15          = np.round(p0 * 2**15).astype(np.int16)
+
+    printVector(f, quant_scales_q8, 'dred_quant_scales_q8', dtype='opus_int16', static=False)
+    printVector(f, dead_zone_q10, 'dred_dead_zone_q10', dtype='opus_int16', static=False)
+    printVector(f, r_q15, 'dred_r_q15', dtype='opus_int16', static=False)
+    printVector(f, p0_q15, 'dred_p0_q15', dtype='opus_int16', static=False)
+
+    fh.write(
+f"""
+extern const float nfec_stats_quant_scales[{levels * N}];
+extern const float nfec_stats_dead_zone_theta[{levels * N}];
+extern const float nfec_stats_r[{levels * N}];
+extern const float nfec_stats_theta[{levels * N}];
+
+"""
+    )
+
+if __name__ == "__main__":
+
+    model, encoder, decoder, qembedding = new_rdovae_model(20, args.latent_dim, cond_size=args.cond_size)
+    model.load_weights(args.weights)
+
+
+
+
+    # encoder
+    encoder_dense_names = [
+        'enc_dense1',
+        'enc_dense3',
+        'enc_dense5',
+        'enc_dense7',
+        'enc_dense8',
+        'gdense1',
+        'gdense2'
+    ]
+
+    encoder_gru_names = [
+        'enc_dense2',
+        'enc_dense4',
+        'enc_dense6'
+    ]
+
+    encoder_conv1d_names = [
+        'bits_dense'
+    ]
+
+    source_fid = open("dred_rdovae_enc_data.c", 'w')
+    header_fid = open("dred_rdovae_enc_data.h", 'w')
+
+    start_header(header_fid, "dred_rdovae_enc_data.h")
+    start_source(source_fid, "dred_rdovae_enc_data.h", os.path.basename(args.weights))
+
+    # dump GRUs
+    max_rnn_neurons_enc = max(
+        [
+            dump_gru_layer(encoder.get_layer(name), source_fid, header_fid)
+            for name in encoder_gru_names
+        ]
+    )
+
+    # dump conv layers
+    max_conv_inputs = max(
+        [
+            dump_conv1d_layer(encoder.get_layer(name), source_fid, header_fid)
+            for name in encoder_conv1d_names
+        ] 
+    )
+
+    # dump Dense layers
+    for name in encoder_dense_names:
+        layer = encoder.get_layer(name)
+        dump_dense_layer(layer, source_fid, header_fid)
+
+    # some global constants
+    header_fid.write(
+f"""
+#include "dred_rdovae_constants.h"
+
+#define DRED_ENC_MAX_RNN_NEURONS {max_rnn_neurons_enc}
+
+#define DRED_ENC_MAX_CONV_INPUTS {max_conv_inputs}
+
+"""
+    )
+
+    finish_header(header_fid)
+    finish_source(source_fid)
+
+    header_fid.close()
+    source_fid.close()
+
+    # statistical model
+    source_fid = open("dred_rdovae_stats_data.c", 'w')
+    header_fid = open("dred_rdovae_stats_data.h", 'w')
+
+    start_header(header_fid, "dred_rdovae_stats_data.h")
+    start_source(source_fid, "dred_rdovae_stats_data.h", os.path.basename(args.weights))
+
+    header_fid.write(
+"""
+
+#include "opus_types.h"
+
+"""
+    )
+
+    dump_statistical_model(qembedding, source_fid, header_fid)
+
+    finish_header(header_fid)
+    finish_source(source_fid)
+
+    header_fid.close()
+    source_fid.close()
+
+    # decoder
+    decoder_dense_names = [
+        'state1',
+        'state2',
+        'state3',
+        'dec_dense1',
+        'dec_dense3',
+        'dec_dense5',
+        'dec_dense7',
+        'dec_dense8',
+        'dec_final'
+    ]   
+
+    decoder_gru_names = [
+        'dec_dense2',
+        'dec_dense4',
+        'dec_dense6'
+    ] 
+
+    source_fid = open("dred_rdovae_dec_data.c", 'w')
+    header_fid = open("dred_rdovae_dec_data.h", 'w')
+
+    start_header(header_fid, "dred_rdovae_dec_data.h")
+    start_source(source_fid, "dred_rdovae_dec_data.h", os.path.basename(args.weights))
+
+
+
+
+    # dump GRUs
+    max_rnn_neurons_dec = max(
+        [
+            dump_gru_layer(decoder.get_layer(name), source_fid, header_fid)
+            for name in decoder_gru_names
+        ]
+    )
+
+    # dump Dense layers
+    for name in decoder_dense_names:
+        layer = decoder.get_layer(name)
+        dump_dense_layer(layer, source_fid, header_fid)
+
+    # some global constants
+    header_fid.write(
+f"""
+#include "dred_rdovae_constants.h"
+
+#define DRED_DEC_MAX_RNN_NEURONS {max_rnn_neurons_dec}
+
+"""
+    )
+
+    finish_header(header_fid)
+    finish_source(source_fid)
+
+    header_fid.close()
+    source_fid.close()
+
+    # common constants
+    header_fid = open("dred_rdovae_constants.h", 'w')
+    start_header(header_fid, "dred_rdovae_constants.h")
+
+    header_fid.write(
+f"""
+#define DRED_NUM_FEATURES 20
+
+#define DRED_LATENT_DIM {args.latent_dim}
+
+#define DRED_NUM_QUANTIZATION_LEVELS {qembedding.weights[0].shape[0]}
+
+#define DRED_MAX_RNN_NEURONS {max(max_rnn_neurons_enc, max_rnn_neurons_dec)}
+
+#define DRED_MAX_CONV_INPUTS {max_conv_inputs}
+"""
+    )
+
+    finish_header(header_fid)
\ No newline at end of file
--