Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.xiph.org/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Buethe <jbuethe@amazon.de>2023-11-30 16:49:32 +0300
committerJan Buethe <jbuethe@amazon.de>2023-11-30 16:49:32 +0300
commit991b56e43e7aad37e20bfbc7d1311718eb695a53 (patch)
tree069e824723bc8da5a7985ad33154d70e794b8439
parentfac47058d99e63a9dfefa6f37eb0ea0b956daa66 (diff)
added AdaShape C implementation
-rw-r--r--dnn/adaconvtest.c107
-rw-r--r--dnn/nndsp.c85
-rw-r--r--dnn/nndsp.h22
-rw-r--r--dnn/torch/osce/create_testvectors.py20
4 files changed, 229 insertions, 5 deletions
diff --git a/dnn/adaconvtest.c b/dnn/adaconvtest.c
index fa7f8cc1..7769be6b 100644
--- a/dnn/adaconvtest.c
+++ b/dnn/adaconvtest.c
@@ -221,6 +221,95 @@ void adacomb_compare(
}
}
+void adashape_compare(
+ const char * prefix,
+ int num_frames,
+ AdaShapeState* hAdaShape,
+ LinearLayer *alpha1,
+ LinearLayer *alpha2,
+ int feature_dim,
+ int frame_size,
+ int avg_pool_k
+)
+{
+ char feature_file[256];
+ char x_in_file[256];
+ char x_out_file[256];
+ char message[512];
+ int i_frame, i_sample;
+ float mse;
+ float features[512];
+ float x_in[512];
+ float x_out_ref[512];
+ float x_out[512];
+
+ init_adashape_state(hAdaShape);
+
+ FILE *f_features, *f_x_in, *f_x_out;
+
+ strcpy(feature_file, prefix);
+ strcat(feature_file, "_features.f32");
+ f_features = fopen(feature_file, "r");
+ if (f_features == NULL)
+ {
+ sprintf(message, "could not open file %s", feature_file);
+ perror(message);
+ exit(1);
+ }
+
+ strcpy(x_in_file, prefix);
+ strcat(x_in_file, "_x_in.f32");
+ f_x_in = fopen(x_in_file, "r");
+ if (f_x_in == NULL)
+ {
+ sprintf(message, "could not open file %s", x_in_file);
+ perror(message);
+ exit(1);
+ }
+
+ strcpy(x_out_file, prefix);
+ strcat(x_out_file, "_x_out.f32");
+ f_x_out = fopen(x_out_file, "r");
+ if (f_x_out == NULL)
+ {
+ sprintf(message, "could not open file %s", x_out_file);
+ perror(message);
+ exit(1);
+ }
+
+ for (i_frame = 0; i_frame < num_frames; i_frame ++)
+ {
+ if (fread(features, sizeof(float), feature_dim, f_features) != feature_dim)
+ {
+ fprintf(stderr, "could not read frame %d from %s\n", i_frame, feature_file);
+ exit(1);
+ }
+
+ if (fread(x_in, sizeof(float), frame_size, f_x_in) != frame_size)
+ {
+ fprintf(stderr, "could not read frame %d from %s\n", i_frame, x_in_file);
+ exit(1);
+ }
+
+ if (fread(x_out_ref, sizeof(float), frame_size, f_x_out) != frame_size)
+ {
+ fprintf(stderr, "could not read frame %d from %s\n", i_frame, x_out_file);
+ exit(1);
+ }
+
+ adashape_process_frame(hAdaShape, x_out, x_in, features, alpha1, alpha2, feature_dim, frame_size, avg_pool_k);
+
+ mse = 0;
+ for (i_sample = 0; i_sample < frame_size; i_sample ++)
+ {
+ mse += pow(x_out_ref[i_sample] - x_out[i_sample], 2);
+ }
+ mse = sqrt(mse / (frame_size));
+ printf("rmse[%d] %f\n", i_frame, mse);
+
+ }
+}
+
int main()
{
@@ -229,12 +318,13 @@ int main()
AdaConvState hAdaConv;
AdaCombState hAdaComb;
+ AdaShapeState hAdaShape;
init_adaconv_state(&hAdaConv);
init_lacelayers(&hLACE, lacelayers_arrays);
init_nolacelayers(&hNoLACE, nolacelayers_arrays);
-
+#if 0
printf("\ntesting lace.af1 (1 in, 1 out)...\n");
adaconv_compare(
"testvectors/lace_af1",
@@ -330,9 +420,22 @@ int main()
LACE_CF1_FILTER_GAIN_B,
LACE_CF1_LOG_GAIN_LIMIT
);
+#endif
+
+ printf("\ntesting nolace.tdshape1...\n");
+ adashape_compare(
+ "testvectors/nolace_tdshape1",
+ 5,
+ &hAdaShape,
+ &hNoLACE.nolace_tdshape1_alpha1,
+ &hNoLACE.nolace_tdshape1_alpha2,
+ NOLACE_TDSHAPE1_FEATURE_DIM,
+ NOLACE_TDSHAPE1_FRAME_SIZE,
+ NOLACE_TDSHAPE1_AVG_POOL_K
+ );
return 0;
}
-//gcc -I ../include -I . -I ../celt adaconvtest.c nndsp.c lace_data.c nolace_data.c nnet.c parse_lpcnet_weights.c -lm -o adaconvtest \ No newline at end of file
+//gcc -I ../include -I ../silk -I . -I ../celt adaconvtest.c nndsp.c lace_data.c nolace_data.c nnet.c parse_lpcnet_weights.c -lm -o adaconvtest \ No newline at end of file
diff --git a/dnn/nndsp.c b/dnn/nndsp.c
index 489b9e7f..c4954eba 100644
--- a/dnn/nndsp.c
+++ b/dnn/nndsp.c
@@ -15,12 +15,17 @@
void init_adaconv_state(AdaConvState *hAdaConv)
{
- memset(hAdaConv, 0, sizeof(*hAdaConv));
+ OPUS_CLEAR(hAdaConv, 1);
}
void init_adacomb_state(AdaCombState *hAdaComb)
{
- memset(hAdaComb, 0, sizeof(*hAdaComb));
+ OPUS_CLEAR(hAdaComb, 1);
+}
+
+void init_adashape_state(AdaShapeState *hAdaShape)
+{
+ OPUS_CLEAR(hAdaShape, 1);
}
#ifdef DEBUG_NNDSP
@@ -302,3 +307,79 @@ void adacomb_process_frame(
hAdaComb->last_pitch_lag = pitch_lag;
hAdaComb->last_global_gain = global_gain;
}
+
+
+void adashape_process_frame(
+ AdaShapeState *hAdaShape,
+ float *x_out,
+ const float *x_in,
+ const float *features,
+ const LinearLayer *alpha1,
+ const LinearLayer *alpha2,
+ int feature_dim,
+ int frame_size,
+ int avg_pool_k
+)
+{
+ float in_buffer[ADASHAPE_MAX_INPUT_DIM + ADASHAPE_MAX_FRAME_SIZE];
+ float out_buffer[ADASHAPE_MAX_FRAME_SIZE];
+ int i, k;
+ int tenv_size;
+ float mean;
+ float *tenv;
+
+ celt_assert(frame_size % avg_pool_k == 0);
+ celt_assert(feature_dim + frame_size / avg_pool_k + 1 < ADASHAPE_MAX_INPUT_DIM);
+
+ tenv_size = frame_size / avg_pool_k;
+ tenv = in_buffer + feature_dim;
+ OPUS_CLEAR(tenv, tenv_size + 1);
+
+ OPUS_COPY(in_buffer, features, feature_dim);
+
+ /* calculate temporal envelope */
+ mean = 0;
+ for (i = 0; i < tenv_size; i++)
+ {
+ for (k = 0; k < avg_pool_k; k++)
+ {
+ tenv[i] += fabs(x_in[i * avg_pool_k + k]);
+ }
+ tenv[i] = log(tenv[i] / avg_pool_k + 1.52587890625e-05f);
+ mean += tenv[i];
+ }
+ mean /= tenv_size;
+ for (i = 0; i < tenv_size; i++)
+ {
+ tenv[i] -= mean;
+ }
+ tenv[tenv_size] = mean;
+#ifdef DEBUG_NNDSP
+ print_float_vector("tenv", tenv, tenv_size + 1);
+#endif
+
+ /* calculate temporal weights */
+#ifdef DEBUG_NNDSP
+ print_float_vector("alpha1_in", in_buffer, feature_dim + tenv_size + 1);
+#endif
+ compute_generic_conv1d(alpha1, out_buffer, hAdaShape->conv_alpha1_state, in_buffer, feature_dim + tenv_size + 1, ACTIVATION_LINEAR);
+#ifdef DEBUG_NNDSP
+ print_float_vector("alpha1_out", out_buffer, frame_size);
+#endif
+ /* compute leaky ReLU by hand. ToDo: try tanh activation */
+ for (i = 0; i < frame_size; i ++)
+ {
+ in_buffer[i] = out_buffer[i] >= 0 ? out_buffer[i] : 0.2 * out_buffer[i];
+ }
+#ifdef DEBUG_NNDSP
+ print_float_vector("post_alpha1", in_buffer, frame_size);
+#endif
+ compute_generic_conv1d(alpha2, out_buffer, hAdaShape->conv_alpha2_state, in_buffer, frame_size, ACTIVATION_LINEAR);
+
+ /* shape signal */
+ for (i = 0; i < frame_size; i ++)
+ {
+ x_out[i] = exp(out_buffer[i]) * x_in[i];
+ }
+
+} \ No newline at end of file
diff --git a/dnn/nndsp.h b/dnn/nndsp.h
index 6846a101..d8dcebe2 100644
--- a/dnn/nndsp.h
+++ b/dnn/nndsp.h
@@ -17,6 +17,9 @@
#define ADACOMB_MAX_FRAME_SIZE 80
#define ADACOMB_MAX_OVERLAP_SIZE 40
+#define ADASHAPE_MAX_INPUT_DIM 512
+#define ADASHAPE_MAX_FRAME_SIZE 160
+
//#define DEBUG_NNDSP
#ifdef DEBUG_NNDSP
#include <stdio.h>
@@ -39,10 +42,17 @@ typedef struct {
} AdaCombState;
+typedef struct {
+ float conv_alpha1_state[ADASHAPE_MAX_INPUT_DIM];
+ float conv_alpha2_state[ADASHAPE_MAX_FRAME_SIZE];
+} AdaShapeState;
+
void init_adaconv_state(AdaConvState *hAdaConv);
void init_adacomb_state(AdaCombState *hAdaComb);
+void init_adashape_state(AdaShapeState *hAdaShape);
+
void adaconv_process_frame(
AdaConvState* hAdaConv,
float *x_out,
@@ -83,6 +93,16 @@ void adacomb_process_frame(
float *window
);
-void adashape_process_frame(void);
+void adashape_process_frame(
+ AdaShapeState *hAdaShape,
+ float *x_out,
+ const float *x_in,
+ const float *features,
+ const LinearLayer *alpha1,
+ const LinearLayer *alpha2,
+ int feature_dim,
+ int frame_size,
+ int avg_pool_k
+);
#endif \ No newline at end of file
diff --git a/dnn/torch/osce/create_testvectors.py b/dnn/torch/osce/create_testvectors.py
index 476e0930..fd03d318 100644
--- a/dnn/torch/osce/create_testvectors.py
+++ b/dnn/torch/osce/create_testvectors.py
@@ -53,6 +53,23 @@ def create_adacomb_testvector(prefix, adacomb, num_frames, debug=False):
p_in.tofile(prefix + '_p_in.s32')
x_out.tofile(prefix + '_x_out.f32')
+def create_adashape_testvector(prefix, adashape, num_frames):
+ feature_dim = adashape.feature_dim
+ frame_size = adashape.frame_size
+
+ features = torch.randn((1, num_frames, feature_dim))
+ x_in = torch.randn((1, 1, num_frames * frame_size))
+
+ x_out = adashape(x_in, features)
+
+ features = features[0].detach().numpy()
+ x_in = x_in.flatten().detach().numpy()
+ x_out = x_out.flatten().detach().numpy()
+
+ features.tofile(prefix + '_features.f32')
+ x_in.tofile(prefix + '_x_in.f32')
+ x_out.tofile(prefix + '_x_out.f32')
+
def create_feature_net_testvector(prefix, model, num_frames):
num_features = model.num_features
num_subframes = 4 * num_frames
@@ -108,6 +125,9 @@ if __name__ == "__main__":
# lace cf1
create_adacomb_testvector(os.path.join(args.output_folder, "lace_cf1"), lace.cf1, 5, debug=args.debug)
+ # nolace tdshape1
+ create_adashape_testvector(os.path.join(args.output_folder, "nolace_tdshape1"), nolace.tdshape1, 5)
+
# lace feature net
create_feature_net_testvector(os.path.join(args.output_folder, 'lace'), lace, 5)