xref: /aosp_15_r20/external/rnnoise/src/rnn_reader.c (revision 1295d6828459cc82c3c29cc5d7d297215250a74b)
1*1295d682SXin Li /* Copyright (c) 2018 Gregor Richards */
2*1295d682SXin Li /*
3*1295d682SXin Li    Redistribution and use in source and binary forms, with or without
4*1295d682SXin Li    modification, are permitted provided that the following conditions
5*1295d682SXin Li    are met:
6*1295d682SXin Li 
7*1295d682SXin Li    - Redistributions of source code must retain the above copyright
8*1295d682SXin Li    notice, this list of conditions and the following disclaimer.
9*1295d682SXin Li 
10*1295d682SXin Li    - Redistributions in binary form must reproduce the above copyright
11*1295d682SXin Li    notice, this list of conditions and the following disclaimer in the
12*1295d682SXin Li    documentation and/or other materials provided with the distribution.
13*1295d682SXin Li 
14*1295d682SXin Li    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15*1295d682SXin Li    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16*1295d682SXin Li    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17*1295d682SXin Li    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
18*1295d682SXin Li    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19*1295d682SXin Li    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20*1295d682SXin Li    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21*1295d682SXin Li    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22*1295d682SXin Li    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23*1295d682SXin Li    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24*1295d682SXin Li    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*1295d682SXin Li */
26*1295d682SXin Li 
27*1295d682SXin Li #ifdef HAVE_CONFIG_H
28*1295d682SXin Li #include "config.h"
29*1295d682SXin Li #endif
30*1295d682SXin Li 
31*1295d682SXin Li #include <stdio.h>
32*1295d682SXin Li #include <stdlib.h>
33*1295d682SXin Li #include <sys/types.h>
34*1295d682SXin Li 
35*1295d682SXin Li #include "rnn.h"
36*1295d682SXin Li #include "rnn_data.h"
37*1295d682SXin Li #include "rnnoise.h"
38*1295d682SXin Li 
39*1295d682SXin Li /* Although these values are the same as in rnn.h, we make them separate to
40*1295d682SXin Li  * avoid accidentally burning internal values into a file format */
41*1295d682SXin Li #define F_ACTIVATION_TANH       0
42*1295d682SXin Li #define F_ACTIVATION_SIGMOID    1
43*1295d682SXin Li #define F_ACTIVATION_RELU       2
44*1295d682SXin Li 
rnnoise_model_from_file(FILE * f)45*1295d682SXin Li RNNModel *rnnoise_model_from_file(FILE *f)
46*1295d682SXin Li {
47*1295d682SXin Li     int i, in;
48*1295d682SXin Li 
49*1295d682SXin Li     if (fscanf(f, "rnnoise-nu model file version %d\n", &in) != 1 || in != 1)
50*1295d682SXin Li         return NULL;
51*1295d682SXin Li 
52*1295d682SXin Li     RNNModel *ret = calloc(1, sizeof(RNNModel));
53*1295d682SXin Li     if (!ret)
54*1295d682SXin Li         return NULL;
55*1295d682SXin Li 
56*1295d682SXin Li #define ALLOC_LAYER(type, name) \
57*1295d682SXin Li     type *name; \
58*1295d682SXin Li     name = calloc(1, sizeof(type)); \
59*1295d682SXin Li     if (!name) { \
60*1295d682SXin Li         rnnoise_model_free(ret); \
61*1295d682SXin Li         return NULL; \
62*1295d682SXin Li     } \
63*1295d682SXin Li     ret->name = name
64*1295d682SXin Li 
65*1295d682SXin Li     ALLOC_LAYER(DenseLayer, input_dense);
66*1295d682SXin Li     ALLOC_LAYER(GRULayer, vad_gru);
67*1295d682SXin Li     ALLOC_LAYER(GRULayer, noise_gru);
68*1295d682SXin Li     ALLOC_LAYER(GRULayer, denoise_gru);
69*1295d682SXin Li     ALLOC_LAYER(DenseLayer, denoise_output);
70*1295d682SXin Li     ALLOC_LAYER(DenseLayer, vad_output);
71*1295d682SXin Li 
72*1295d682SXin Li #define INPUT_VAL(name) do { \
73*1295d682SXin Li     if (fscanf(f, "%d", &in) != 1 || in < 0 || in > 128) { \
74*1295d682SXin Li         rnnoise_model_free(ret); \
75*1295d682SXin Li         return NULL; \
76*1295d682SXin Li     } \
77*1295d682SXin Li     name = in; \
78*1295d682SXin Li     } while (0)
79*1295d682SXin Li 
80*1295d682SXin Li #define INPUT_ACTIVATION(name) do { \
81*1295d682SXin Li     int activation; \
82*1295d682SXin Li     INPUT_VAL(activation); \
83*1295d682SXin Li     switch (activation) { \
84*1295d682SXin Li         case F_ACTIVATION_SIGMOID: \
85*1295d682SXin Li             name = ACTIVATION_SIGMOID; \
86*1295d682SXin Li             break; \
87*1295d682SXin Li         case F_ACTIVATION_RELU: \
88*1295d682SXin Li             name = ACTIVATION_RELU; \
89*1295d682SXin Li             break; \
90*1295d682SXin Li         default: \
91*1295d682SXin Li             name = ACTIVATION_TANH; \
92*1295d682SXin Li     } \
93*1295d682SXin Li     } while (0)
94*1295d682SXin Li 
95*1295d682SXin Li #define INPUT_ARRAY(name, len) do { \
96*1295d682SXin Li     rnn_weight *values = malloc((len) * sizeof(rnn_weight)); \
97*1295d682SXin Li     if (!values) { \
98*1295d682SXin Li         rnnoise_model_free(ret); \
99*1295d682SXin Li         return NULL; \
100*1295d682SXin Li     } \
101*1295d682SXin Li     name = values; \
102*1295d682SXin Li     for (i = 0; i < (len); i++) { \
103*1295d682SXin Li         if (fscanf(f, "%d", &in) != 1) { \
104*1295d682SXin Li             rnnoise_model_free(ret); \
105*1295d682SXin Li             return NULL; \
106*1295d682SXin Li         } \
107*1295d682SXin Li         values[i] = in; \
108*1295d682SXin Li     } \
109*1295d682SXin Li     } while (0)
110*1295d682SXin Li 
111*1295d682SXin Li #define INPUT_DENSE(name) do { \
112*1295d682SXin Li     INPUT_VAL(name->nb_inputs); \
113*1295d682SXin Li     INPUT_VAL(name->nb_neurons); \
114*1295d682SXin Li     ret->name ## _size = name->nb_neurons; \
115*1295d682SXin Li     INPUT_ACTIVATION(name->activation); \
116*1295d682SXin Li     INPUT_ARRAY(name->input_weights, name->nb_inputs * name->nb_neurons); \
117*1295d682SXin Li     INPUT_ARRAY(name->bias, name->nb_neurons); \
118*1295d682SXin Li     } while (0)
119*1295d682SXin Li 
120*1295d682SXin Li #define INPUT_GRU(name) do { \
121*1295d682SXin Li     INPUT_VAL(name->nb_inputs); \
122*1295d682SXin Li     INPUT_VAL(name->nb_neurons); \
123*1295d682SXin Li     ret->name ## _size = name->nb_neurons; \
124*1295d682SXin Li     INPUT_ACTIVATION(name->activation); \
125*1295d682SXin Li     INPUT_ARRAY(name->input_weights, name->nb_inputs * name->nb_neurons * 3); \
126*1295d682SXin Li     INPUT_ARRAY(name->recurrent_weights, name->nb_neurons * name->nb_neurons * 3); \
127*1295d682SXin Li     INPUT_ARRAY(name->bias, name->nb_neurons * 3); \
128*1295d682SXin Li     } while (0)
129*1295d682SXin Li 
130*1295d682SXin Li     INPUT_DENSE(input_dense);
131*1295d682SXin Li     INPUT_GRU(vad_gru);
132*1295d682SXin Li     INPUT_GRU(noise_gru);
133*1295d682SXin Li     INPUT_GRU(denoise_gru);
134*1295d682SXin Li     INPUT_DENSE(denoise_output);
135*1295d682SXin Li     INPUT_DENSE(vad_output);
136*1295d682SXin Li 
137*1295d682SXin Li     return ret;
138*1295d682SXin Li }
139*1295d682SXin Li 
rnnoise_model_free(RNNModel * model)140*1295d682SXin Li void rnnoise_model_free(RNNModel *model)
141*1295d682SXin Li {
142*1295d682SXin Li #define FREE_MAYBE(ptr) do { if (ptr) free(ptr); } while (0)
143*1295d682SXin Li #define FREE_DENSE(name) do { \
144*1295d682SXin Li     if (model->name) { \
145*1295d682SXin Li         free((void *) model->name->input_weights); \
146*1295d682SXin Li         free((void *) model->name->bias); \
147*1295d682SXin Li         free((void *) model->name); \
148*1295d682SXin Li     } \
149*1295d682SXin Li     } while (0)
150*1295d682SXin Li #define FREE_GRU(name) do { \
151*1295d682SXin Li     if (model->name) { \
152*1295d682SXin Li         free((void *) model->name->input_weights); \
153*1295d682SXin Li         free((void *) model->name->recurrent_weights); \
154*1295d682SXin Li         free((void *) model->name->bias); \
155*1295d682SXin Li         free((void *) model->name); \
156*1295d682SXin Li     } \
157*1295d682SXin Li     } while (0)
158*1295d682SXin Li 
159*1295d682SXin Li     if (!model)
160*1295d682SXin Li         return;
161*1295d682SXin Li     FREE_DENSE(input_dense);
162*1295d682SXin Li     FREE_GRU(vad_gru);
163*1295d682SXin Li     FREE_GRU(noise_gru);
164*1295d682SXin Li     FREE_GRU(denoise_gru);
165*1295d682SXin Li     FREE_DENSE(denoise_output);
166*1295d682SXin Li     FREE_DENSE(vad_output);
167*1295d682SXin Li     free(model);
168*1295d682SXin Li }
169