diff options
author | Jan Buethe <jbuethe@amazon.de> | 2023-11-30 16:49:32 +0300 |
---|---|---|
committer | Jan Buethe <jbuethe@amazon.de> | 2023-11-30 16:49:32 +0300 |
commit | 991b56e43e7aad37e20bfbc7d1311718eb695a53 (patch) | |
tree | 069e824723bc8da5a7985ad33154d70e794b8439 | |
parent | fac47058d99e63a9dfefa6f37eb0ea0b956daa66 (diff) |
added AdaShape C implementation
-rw-r--r-- | dnn/adaconvtest.c | 107 | ||||
-rw-r--r-- | dnn/nndsp.c | 85 | ||||
-rw-r--r-- | dnn/nndsp.h | 22 | ||||
-rw-r--r-- | dnn/torch/osce/create_testvectors.py | 20 |
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) |