1*a58d3d2aSXin Li #ifdef HAVE_CONFIG_H
2*a58d3d2aSXin Li #include "config.h"
3*a58d3d2aSXin Li #endif
4*a58d3d2aSXin Li
5*a58d3d2aSXin Li #include <math.h>
6*a58d3d2aSXin Li #include "pitchdnn.h"
7*a58d3d2aSXin Li #include "os_support.h"
8*a58d3d2aSXin Li #include "nnet.h"
9*a58d3d2aSXin Li #include "lpcnet_private.h"
10*a58d3d2aSXin Li
11*a58d3d2aSXin Li
compute_pitchdnn(PitchDNNState * st,const float * if_features,const float * xcorr_features,int arch)12*a58d3d2aSXin Li float compute_pitchdnn(
13*a58d3d2aSXin Li PitchDNNState *st,
14*a58d3d2aSXin Li const float *if_features,
15*a58d3d2aSXin Li const float *xcorr_features,
16*a58d3d2aSXin Li int arch
17*a58d3d2aSXin Li )
18*a58d3d2aSXin Li {
19*a58d3d2aSXin Li float if1_out[DENSE_IF_UPSAMPLER_1_OUT_SIZE];
20*a58d3d2aSXin Li float downsampler_in[NB_XCORR_FEATURES + DENSE_IF_UPSAMPLER_2_OUT_SIZE];
21*a58d3d2aSXin Li float downsampler_out[DENSE_DOWNSAMPLER_OUT_SIZE];
22*a58d3d2aSXin Li float conv1_tmp1[(NB_XCORR_FEATURES + 2)*8] = {0};
23*a58d3d2aSXin Li float conv1_tmp2[(NB_XCORR_FEATURES + 2)*8] = {0};
24*a58d3d2aSXin Li float output[DENSE_FINAL_UPSAMPLER_OUT_SIZE];
25*a58d3d2aSXin Li int i;
26*a58d3d2aSXin Li int pos=0;
27*a58d3d2aSXin Li float maxval=-1;
28*a58d3d2aSXin Li float sum=0;
29*a58d3d2aSXin Li float count=0;
30*a58d3d2aSXin Li PitchDNN *model = &st->model;
31*a58d3d2aSXin Li /* IF */
32*a58d3d2aSXin Li compute_generic_dense(&model->dense_if_upsampler_1, if1_out, if_features, ACTIVATION_TANH, arch);
33*a58d3d2aSXin Li compute_generic_dense(&model->dense_if_upsampler_2, &downsampler_in[NB_XCORR_FEATURES], if1_out, ACTIVATION_TANH, arch);
34*a58d3d2aSXin Li /* xcorr*/
35*a58d3d2aSXin Li OPUS_COPY(&conv1_tmp1[1], xcorr_features, NB_XCORR_FEATURES);
36*a58d3d2aSXin Li compute_conv2d(&model->conv2d_1, &conv1_tmp2[1], st->xcorr_mem1, conv1_tmp1, NB_XCORR_FEATURES, NB_XCORR_FEATURES+2, ACTIVATION_TANH, arch);
37*a58d3d2aSXin Li compute_conv2d(&model->conv2d_2, downsampler_in, st->xcorr_mem2, conv1_tmp2, NB_XCORR_FEATURES, NB_XCORR_FEATURES, ACTIVATION_TANH, arch);
38*a58d3d2aSXin Li
39*a58d3d2aSXin Li compute_generic_dense(&model->dense_downsampler, downsampler_out, downsampler_in, ACTIVATION_TANH, arch);
40*a58d3d2aSXin Li compute_generic_gru(&model->gru_1_input, &model->gru_1_recurrent, st->gru_state, downsampler_out, arch);
41*a58d3d2aSXin Li compute_generic_dense(&model->dense_final_upsampler, output, st->gru_state, ACTIVATION_LINEAR, arch);
42*a58d3d2aSXin Li for (i=0;i<180;i++) {
43*a58d3d2aSXin Li if (output[i] > maxval) {
44*a58d3d2aSXin Li pos = i;
45*a58d3d2aSXin Li maxval = output[i];
46*a58d3d2aSXin Li }
47*a58d3d2aSXin Li }
48*a58d3d2aSXin Li for (i=IMAX(0, pos-2); i<=IMIN(179, pos+2); i++) {
49*a58d3d2aSXin Li float p = exp(output[i]);
50*a58d3d2aSXin Li sum += p*i;
51*a58d3d2aSXin Li count += p;
52*a58d3d2aSXin Li }
53*a58d3d2aSXin Li /*printf("%d %f\n", pos, sum/count);*/
54*a58d3d2aSXin Li return (1.f/60.f)*(sum/count) - 1.5;
55*a58d3d2aSXin Li /*return 256.f/pow(2.f, (1.f/60.f)*i);*/
56*a58d3d2aSXin Li }
57*a58d3d2aSXin Li
58*a58d3d2aSXin Li
pitchdnn_init(PitchDNNState * st)59*a58d3d2aSXin Li void pitchdnn_init(PitchDNNState *st)
60*a58d3d2aSXin Li {
61*a58d3d2aSXin Li int ret;
62*a58d3d2aSXin Li OPUS_CLEAR(st, 1);
63*a58d3d2aSXin Li #ifndef USE_WEIGHTS_FILE
64*a58d3d2aSXin Li ret = init_pitchdnn(&st->model, pitchdnn_arrays);
65*a58d3d2aSXin Li #else
66*a58d3d2aSXin Li ret = 0;
67*a58d3d2aSXin Li #endif
68*a58d3d2aSXin Li celt_assert(ret == 0);
69*a58d3d2aSXin Li }
70*a58d3d2aSXin Li
pitchdnn_load_model(PitchDNNState * st,const void * data,int len)71*a58d3d2aSXin Li int pitchdnn_load_model(PitchDNNState *st, const void *data, int len) {
72*a58d3d2aSXin Li WeightArray *list;
73*a58d3d2aSXin Li int ret;
74*a58d3d2aSXin Li parse_weights(&list, data, len);
75*a58d3d2aSXin Li ret = init_pitchdnn(&st->model, list);
76*a58d3d2aSXin Li opus_free(list);
77*a58d3d2aSXin Li if (ret == 0) return 0;
78*a58d3d2aSXin Li else return -1;
79*a58d3d2aSXin Li }
80