Fangjun Kuang
Committed by GitHub

Refactor node-addon-api to remove duplicate. (#873)

@@ -77,4 +77,19 @@ jobs: @@ -77,4 +77,19 @@ jobs:
77 77
78 cd /shared 78 cd /shared
79 79
  80 + d=nodejs-addon-examples
  81 + echo "dir: $d"
  82 + cd $d
  83 + npm install --verbose
  84 + git status
  85 + ls -lh
  86 + ls -lh node_modules
  87 +
  88 + export DYLD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-darwin-x64:$DYLD_LIBRARY_PATH
  89 + export DYLD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-darwin-arm64:$DYLD_LIBRARY_PATH
  90 + export LD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-linux-x64:$LD_LIBRARY_PATH
  91 + export LD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-linux-arm64:$LD_LIBRARY_PATH
  92 +
  93 + cd ../
  94 +
80 .github/scripts/test-nodejs-addon-npm.sh 95 .github/scripts/test-nodejs-addon-npm.sh
  1 +// scripts/node-addon-api/src/macros.h
  2 +//
  3 +// Copyright (c) 2024 Xiaomi Corporation
  4 +#ifndef SCRIPTS_NODE_ADDON_API_SRC_MACROS_H_
  5 +#define SCRIPTS_NODE_ADDON_API_SRC_MACROS_H_
  6 +
  7 +#include <algorithm>
  8 +#include <string>
  9 +
  10 +#define SHERPA_ONNX_ASSIGN_ATTR_STR(c_name, js_name) \
  11 + do { \
  12 + if (o.Has(#js_name) && o.Get(#js_name).IsString()) { \
  13 + Napi::String _str = o.Get(#js_name).As<Napi::String>(); \
  14 + std::string s = _str.Utf8Value(); \
  15 + char *p = new char[s.size() + 1]; \
  16 + std::copy(s.begin(), s.end(), p); \
  17 + p[s.size()] = 0; \
  18 + \
  19 + c.c_name = p; \
  20 + } \
  21 + } while (0)
  22 +
  23 +#define SHERPA_ONNX_ASSIGN_ATTR_INT32(c_name, js_name) \
  24 + do { \
  25 + if (o.Has(#js_name) && o.Get(#js_name).IsNumber()) { \
  26 + c.c_name = o.Get(#js_name).As<Napi::Number>().Int32Value(); \
  27 + } \
  28 + } while (0)
  29 +
  30 +#define SHERPA_ONNX_ASSIGN_ATTR_FLOAT(c_name, js_name) \
  31 + do { \
  32 + if (o.Has(#js_name) && o.Get(#js_name).IsNumber()) { \
  33 + c.c_name = o.Get(#js_name).As<Napi::Number>().FloatValue(); \
  34 + } \
  35 + } while (0)
  36 +
  37 +#endif // SCRIPTS_NODE_ADDON_API_SRC_MACROS_H_
@@ -3,7 +3,8 @@ @@ -3,7 +3,8 @@
3 // Copyright (c) 2024 Xiaomi Corporation 3 // Copyright (c) 2024 Xiaomi Corporation
4 #include <sstream> 4 #include <sstream>
5 5
6 -#include "napi.h" // NOLINT 6 +#include "macros.h" // NOLINT
  7 +#include "napi.h" // NOLINT
7 #include "sherpa-onnx/c-api/c-api.h" 8 #include "sherpa-onnx/c-api/c-api.h"
8 9
9 // defined in ./streaming-asr.cc 10 // defined in ./streaming-asr.cc
@@ -11,172 +12,87 @@ SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj); @@ -11,172 +12,87 @@ SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj);
11 12
12 static SherpaOnnxOfflineTransducerModelConfig GetOfflineTransducerModelConfig( 13 static SherpaOnnxOfflineTransducerModelConfig GetOfflineTransducerModelConfig(
13 Napi::Object obj) { 14 Napi::Object obj) {
14 - SherpaOnnxOfflineTransducerModelConfig config;  
15 - memset(&config, 0, sizeof(config)); 15 + SherpaOnnxOfflineTransducerModelConfig c;
  16 + memset(&c, 0, sizeof(c));
16 17
17 if (!obj.Has("transducer") || !obj.Get("transducer").IsObject()) { 18 if (!obj.Has("transducer") || !obj.Get("transducer").IsObject()) {
18 - return config; 19 + return c;
19 } 20 }
20 21
21 Napi::Object o = obj.Get("transducer").As<Napi::Object>(); 22 Napi::Object o = obj.Get("transducer").As<Napi::Object>();
22 23
23 - if (o.Has("encoder") && o.Get("encoder").IsString()) {  
24 - Napi::String encoder = o.Get("encoder").As<Napi::String>();  
25 - std::string s = encoder.Utf8Value();  
26 - char *p = new char[s.size() + 1];  
27 - std::copy(s.begin(), s.end(), p);  
28 - p[s.size()] = 0;  
29 -  
30 - config.encoder = p;  
31 - }  
32 -  
33 - if (o.Has("decoder") && o.Get("decoder").IsString()) {  
34 - Napi::String decoder = o.Get("decoder").As<Napi::String>();  
35 - std::string s = decoder.Utf8Value();  
36 - char *p = new char[s.size() + 1];  
37 - std::copy(s.begin(), s.end(), p);  
38 - p[s.size()] = 0;  
39 -  
40 - config.decoder = p;  
41 - }  
42 -  
43 - if (o.Has("joiner") && o.Get("joiner").IsString()) {  
44 - Napi::String joiner = o.Get("joiner").As<Napi::String>();  
45 - std::string s = joiner.Utf8Value();  
46 - char *p = new char[s.size() + 1];  
47 - std::copy(s.begin(), s.end(), p);  
48 - p[s.size()] = 0; 24 + SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
  25 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
  26 + SHERPA_ONNX_ASSIGN_ATTR_STR(joiner, joiner);
49 27
50 - config.joiner = p;  
51 - }  
52 -  
53 - return config; 28 + return c;
54 } 29 }
55 30
56 static SherpaOnnxOfflineParaformerModelConfig GetOfflineParaformerModelConfig( 31 static SherpaOnnxOfflineParaformerModelConfig GetOfflineParaformerModelConfig(
57 Napi::Object obj) { 32 Napi::Object obj) {
58 - SherpaOnnxOfflineParaformerModelConfig config;  
59 - memset(&config, 0, sizeof(config)); 33 + SherpaOnnxOfflineParaformerModelConfig c;
  34 + memset(&c, 0, sizeof(c));
60 35
61 if (!obj.Has("paraformer") || !obj.Get("paraformer").IsObject()) { 36 if (!obj.Has("paraformer") || !obj.Get("paraformer").IsObject()) {
62 - return config; 37 + return c;
63 } 38 }
64 39
65 Napi::Object o = obj.Get("paraformer").As<Napi::Object>(); 40 Napi::Object o = obj.Get("paraformer").As<Napi::Object>();
66 41
67 - if (o.Has("model") && o.Get("model").IsString()) {  
68 - Napi::String model = o.Get("model").As<Napi::String>();  
69 - std::string s = model.Utf8Value();  
70 - char *p = new char[s.size() + 1];  
71 - std::copy(s.begin(), s.end(), p);  
72 - p[s.size()] = 0;  
73 -  
74 - config.model = p;  
75 - } 42 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
76 43
77 - return config; 44 + return c;
78 } 45 }
79 46
80 static SherpaOnnxOfflineNemoEncDecCtcModelConfig GetOfflineNeMoCtcModelConfig( 47 static SherpaOnnxOfflineNemoEncDecCtcModelConfig GetOfflineNeMoCtcModelConfig(
81 Napi::Object obj) { 48 Napi::Object obj) {
82 - SherpaOnnxOfflineNemoEncDecCtcModelConfig config;  
83 - memset(&config, 0, sizeof(config)); 49 + SherpaOnnxOfflineNemoEncDecCtcModelConfig c;
  50 + memset(&c, 0, sizeof(c));
84 51
85 if (!obj.Has("nemoCtc") || !obj.Get("nemoCtc").IsObject()) { 52 if (!obj.Has("nemoCtc") || !obj.Get("nemoCtc").IsObject()) {
86 - return config; 53 + return c;
87 } 54 }
88 55
89 Napi::Object o = obj.Get("nemoCtc").As<Napi::Object>(); 56 Napi::Object o = obj.Get("nemoCtc").As<Napi::Object>();
90 57
91 - if (o.Has("model") && o.Get("model").IsString()) {  
92 - Napi::String model = o.Get("model").As<Napi::String>();  
93 - std::string s = model.Utf8Value();  
94 - char *p = new char[s.size() + 1];  
95 - std::copy(s.begin(), s.end(), p);  
96 - p[s.size()] = 0;  
97 -  
98 - config.model = p;  
99 - } 58 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
100 59
101 - return config; 60 + return c;
102 } 61 }
103 62
104 static SherpaOnnxOfflineWhisperModelConfig GetOfflineWhisperModelConfig( 63 static SherpaOnnxOfflineWhisperModelConfig GetOfflineWhisperModelConfig(
105 Napi::Object obj) { 64 Napi::Object obj) {
106 - SherpaOnnxOfflineWhisperModelConfig config;  
107 - memset(&config, 0, sizeof(config)); 65 + SherpaOnnxOfflineWhisperModelConfig c;
  66 + memset(&c, 0, sizeof(c));
108 67
109 if (!obj.Has("whisper") || !obj.Get("whisper").IsObject()) { 68 if (!obj.Has("whisper") || !obj.Get("whisper").IsObject()) {
110 - return config; 69 + return c;
111 } 70 }
112 71
113 Napi::Object o = obj.Get("whisper").As<Napi::Object>(); 72 Napi::Object o = obj.Get("whisper").As<Napi::Object>();
114 73
115 - if (o.Has("encoder") && o.Get("encoder").IsString()) {  
116 - Napi::String encoder = o.Get("encoder").As<Napi::String>();  
117 - std::string s = encoder.Utf8Value();  
118 - char *p = new char[s.size() + 1];  
119 - std::copy(s.begin(), s.end(), p);  
120 - p[s.size()] = 0;  
121 -  
122 - config.encoder = p;  
123 - }  
124 -  
125 - if (o.Has("decoder") && o.Get("decoder").IsString()) {  
126 - Napi::String decoder = o.Get("decoder").As<Napi::String>();  
127 - std::string s = decoder.Utf8Value();  
128 - char *p = new char[s.size() + 1];  
129 - std::copy(s.begin(), s.end(), p);  
130 - p[s.size()] = 0;  
131 -  
132 - config.decoder = p;  
133 - }  
134 -  
135 - if (o.Has("language") && o.Get("language").IsString()) {  
136 - Napi::String language = o.Get("language").As<Napi::String>();  
137 - std::string s = language.Utf8Value();  
138 - char *p = new char[s.size() + 1];  
139 - std::copy(s.begin(), s.end(), p);  
140 - p[s.size()] = 0;  
141 -  
142 - config.language = p;  
143 - }  
144 -  
145 - if (o.Has("task") && o.Get("task").IsString()) {  
146 - Napi::String task = o.Get("task").As<Napi::String>();  
147 - std::string s = task.Utf8Value();  
148 - char *p = new char[s.size() + 1];  
149 - std::copy(s.begin(), s.end(), p);  
150 - p[s.size()] = 0;  
151 -  
152 - config.task = p;  
153 - } 74 + SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
  75 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
  76 + SHERPA_ONNX_ASSIGN_ATTR_STR(language, language);
  77 + SHERPA_ONNX_ASSIGN_ATTR_STR(task, languagek);
154 78
155 - return config; 79 + return c;
156 } 80 }
157 81
158 static SherpaOnnxOfflineTdnnModelConfig GetOfflineTdnnModelConfig( 82 static SherpaOnnxOfflineTdnnModelConfig GetOfflineTdnnModelConfig(
159 Napi::Object obj) { 83 Napi::Object obj) {
160 - SherpaOnnxOfflineTdnnModelConfig config;  
161 - memset(&config, 0, sizeof(config)); 84 + SherpaOnnxOfflineTdnnModelConfig c;
  85 + memset(&c, 0, sizeof(c));
162 86
163 if (!obj.Has("tdnn") || !obj.Get("tdnn").IsObject()) { 87 if (!obj.Has("tdnn") || !obj.Get("tdnn").IsObject()) {
164 - return config; 88 + return c;
165 } 89 }
166 90
167 Napi::Object o = obj.Get("tdnn").As<Napi::Object>(); 91 Napi::Object o = obj.Get("tdnn").As<Napi::Object>();
168 92
169 - if (o.Has("model") && o.Get("model").IsString()) {  
170 - Napi::String model = o.Get("model").As<Napi::String>();  
171 - std::string s = model.Utf8Value();  
172 - char *p = new char[s.size() + 1];  
173 - std::copy(s.begin(), s.end(), p);  
174 - p[s.size()] = 0;  
175 -  
176 - config.model = p;  
177 - } 93 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
178 94
179 - return config; 95 + return c;
180 } 96 }
181 97
182 static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) { 98 static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
@@ -195,19 +111,8 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) { @@ -195,19 +111,8 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
195 c.whisper = GetOfflineWhisperModelConfig(o); 111 c.whisper = GetOfflineWhisperModelConfig(o);
196 c.tdnn = GetOfflineTdnnModelConfig(o); 112 c.tdnn = GetOfflineTdnnModelConfig(o);
197 113
198 - if (o.Has("tokens") && o.Get("tokens").IsString()) {  
199 - Napi::String tokens = o.Get("tokens").As<Napi::String>();  
200 - std::string s = tokens.Utf8Value();  
201 - char *p = new char[s.size() + 1];  
202 - std::copy(s.begin(), s.end(), p);  
203 - p[s.size()] = 0;  
204 -  
205 - c.tokens = p;  
206 - }  
207 -  
208 - if (o.Has("numThreads") && o.Get("numThreads").IsNumber()) {  
209 - c.num_threads = o.Get("numThreads").As<Napi::Number>().Int32Value();  
210 - } 114 + SHERPA_ONNX_ASSIGN_ATTR_STR(tokens, tokens);
  115 + SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, numThreads);
211 116
212 if (o.Has("debug") && 117 if (o.Has("debug") &&
213 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) { 118 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) {
@@ -218,25 +123,8 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) { @@ -218,25 +123,8 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
218 } 123 }
219 } 124 }
220 125
221 - if (o.Has("provider") && o.Get("provider").IsString()) {  
222 - Napi::String provider = o.Get("provider").As<Napi::String>();  
223 - std::string s = provider.Utf8Value();  
224 - char *p = new char[s.size() + 1];  
225 - std::copy(s.begin(), s.end(), p);  
226 - p[s.size()] = 0;  
227 -  
228 - c.provider = p;  
229 - }  
230 -  
231 - if (o.Has("modelType") && o.Get("modelType").IsString()) {  
232 - Napi::String model_type = o.Get("modelType").As<Napi::String>();  
233 - std::string s = model_type.Utf8Value();  
234 - char *p = new char[s.size() + 1];  
235 - std::copy(s.begin(), s.end(), p);  
236 - p[s.size()] = 0;  
237 -  
238 - c.model_type = p;  
239 - } 126 + SHERPA_ONNX_ASSIGN_ATTR_STR(provider, provider);
  127 + SHERPA_ONNX_ASSIGN_ATTR_STR(model_type, modelType);
240 128
241 return c; 129 return c;
242 } 130 }
@@ -251,19 +139,8 @@ static SherpaOnnxOfflineLMConfig GetOfflineLMConfig(Napi::Object obj) { @@ -251,19 +139,8 @@ static SherpaOnnxOfflineLMConfig GetOfflineLMConfig(Napi::Object obj) {
251 139
252 Napi::Object o = obj.Get("lmConfig").As<Napi::Object>(); 140 Napi::Object o = obj.Get("lmConfig").As<Napi::Object>();
253 141
254 - if (o.Has("model") && o.Get("model").IsString()) {  
255 - Napi::String model = o.Get("model").As<Napi::String>();  
256 - std::string s = model.Utf8Value();  
257 - char *p = new char[s.size() + 1];  
258 - std::copy(s.begin(), s.end(), p);  
259 - p[s.size()] = 0;  
260 -  
261 - c.model = p;  
262 - }  
263 -  
264 - if (o.Has("scale") && o.Get("scale").IsNumber()) {  
265 - c.scale = o.Get("scale").As<Napi::Number>().FloatValue();  
266 - } 142 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
  143 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(scale, scale);
267 144
268 return c; 145 return c;
269 } 146 }
@@ -295,34 +172,10 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { @@ -295,34 +172,10 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) {
295 c.model_config = GetOfflineModelConfig(o); 172 c.model_config = GetOfflineModelConfig(o);
296 c.lm_config = GetOfflineLMConfig(o); 173 c.lm_config = GetOfflineLMConfig(o);
297 174
298 - if (o.Has("decodingMethod") && o.Get("decodingMethod").IsString()) {  
299 - Napi::String decoding_method = o.Get("decodingMethod").As<Napi::String>();  
300 - std::string s = decoding_method.Utf8Value();  
301 - char *p = new char[s.size() + 1];  
302 - std::copy(s.begin(), s.end(), p);  
303 - p[s.size()] = 0;  
304 -  
305 - c.decoding_method = p;  
306 - }  
307 -  
308 - if (o.Has("maxActivePaths") && o.Get("maxActivePaths").IsNumber()) {  
309 - c.max_active_paths =  
310 - o.Get("maxActivePaths").As<Napi::Number>().Int32Value();  
311 - }  
312 -  
313 - if (o.Has("hotwordsFile") && o.Get("hotwordsFile").IsString()) {  
314 - Napi::String hotwords_file = o.Get("hotwordsFile").As<Napi::String>();  
315 - std::string s = hotwords_file.Utf8Value();  
316 - char *p = new char[s.size() + 1];  
317 - std::copy(s.begin(), s.end(), p);  
318 - p[s.size()] = 0;  
319 -  
320 - c.hotwords_file = p;  
321 - }  
322 -  
323 - if (o.Has("hotwordsScore") && o.Get("hotwordsScore").IsNumber()) {  
324 - c.hotwords_score = o.Get("hotwordsScore").As<Napi::Number>().FloatValue();  
325 - } 175 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoding_method, decodingMethod);
  176 + SHERPA_ONNX_ASSIGN_ATTR_INT32(max_active_paths, maxActivePaths);
  177 + SHERPA_ONNX_ASSIGN_ATTR_STR(hotwords_file, hotwordsFile);
  178 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(hotwords_score, hotwordsScore);
326 179
327 SherpaOnnxOfflineRecognizer *recognizer = CreateOfflineRecognizer(&c); 180 SherpaOnnxOfflineRecognizer *recognizer = CreateOfflineRecognizer(&c);
328 181
@@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 -#include "napi.h" // NOLINT 7 +#include "macros.h" // NOLINT
  8 +#include "napi.h" // NOLINT
8 #include "sherpa-onnx/c-api/c-api.h" 9 #include "sherpa-onnx/c-api/c-api.h"
9 10
10 static SherpaOnnxOfflineTtsVitsModelConfig GetOfflineTtsVitsModelConfig( 11 static SherpaOnnxOfflineTtsVitsModelConfig GetOfflineTtsVitsModelConfig(
@@ -17,68 +18,14 @@ static SherpaOnnxOfflineTtsVitsModelConfig GetOfflineTtsVitsModelConfig( @@ -17,68 +18,14 @@ static SherpaOnnxOfflineTtsVitsModelConfig GetOfflineTtsVitsModelConfig(
17 } 18 }
18 19
19 Napi::Object o = obj.Get("vits").As<Napi::Object>(); 20 Napi::Object o = obj.Get("vits").As<Napi::Object>();
20 -  
21 - if (o.Has("model") && o.Get("model").IsString()) {  
22 - Napi::String model = o.Get("model").As<Napi::String>();  
23 - std::string s = model.Utf8Value();  
24 - char *p = new char[s.size() + 1];  
25 - std::copy(s.begin(), s.end(), p);  
26 - p[s.size()] = 0;  
27 -  
28 - c.model = p;  
29 - }  
30 -  
31 - if (o.Has("lexicon") && o.Get("lexicon").IsString()) {  
32 - Napi::String lexicon = o.Get("lexicon").As<Napi::String>();  
33 - std::string s = lexicon.Utf8Value();  
34 - char *p = new char[s.size() + 1];  
35 - std::copy(s.begin(), s.end(), p);  
36 - p[s.size()] = 0;  
37 -  
38 - c.lexicon = p;  
39 - }  
40 -  
41 - if (o.Has("tokens") && o.Get("tokens").IsString()) {  
42 - Napi::String tokens = o.Get("tokens").As<Napi::String>();  
43 - std::string s = tokens.Utf8Value();  
44 - char *p = new char[s.size() + 1];  
45 - std::copy(s.begin(), s.end(), p);  
46 - p[s.size()] = 0;  
47 -  
48 - c.tokens = p;  
49 - }  
50 -  
51 - if (o.Has("dataDir") && o.Get("dataDir").IsString()) {  
52 - Napi::String data_dir = o.Get("dataDir").As<Napi::String>();  
53 - std::string s = data_dir.Utf8Value();  
54 - char *p = new char[s.size() + 1];  
55 - std::copy(s.begin(), s.end(), p);  
56 - p[s.size()] = 0;  
57 -  
58 - c.data_dir = p;  
59 - }  
60 -  
61 - if (o.Has("noiseScale") && o.Get("noiseScale").IsNumber()) {  
62 - c.noise_scale = o.Get("noiseScale").As<Napi::Number>().FloatValue();  
63 - }  
64 -  
65 - if (o.Has("noiseScaleW") && o.Get("noiseScaleW").IsNumber()) {  
66 - c.noise_scale_w = o.Get("noiseScaleW").As<Napi::Number>().FloatValue();  
67 - }  
68 -  
69 - if (o.Has("lengthScale") && o.Get("lengthScale").IsNumber()) {  
70 - c.length_scale = o.Get("lengthScale").As<Napi::Number>().FloatValue();  
71 - }  
72 -  
73 - if (o.Has("dictDir") && o.Get("dictDir").IsString()) {  
74 - Napi::String dict_dir = o.Get("dictDir").As<Napi::String>();  
75 - std::string s = dict_dir.Utf8Value();  
76 - char *p = new char[s.size() + 1];  
77 - std::copy(s.begin(), s.end(), p);  
78 - p[s.size()] = 0;  
79 -  
80 - c.dict_dir = p;  
81 - } 21 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
  22 + SHERPA_ONNX_ASSIGN_ATTR_STR(lexicon, lexicon);
  23 + SHERPA_ONNX_ASSIGN_ATTR_STR(tokens, tokens);
  24 + SHERPA_ONNX_ASSIGN_ATTR_STR(data_dir, dataDir);
  25 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(noise_scale, noiseScale);
  26 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(noise_scale_w, noiseScaleW);
  27 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(length_scale, lengthScale);
  28 + SHERPA_ONNX_ASSIGN_ATTR_STR(dict_dir, dictDir);
82 29
83 return c; 30 return c;
84 } 31 }
@@ -96,9 +43,7 @@ static SherpaOnnxOfflineTtsModelConfig GetOfflineTtsModelConfig( @@ -96,9 +43,7 @@ static SherpaOnnxOfflineTtsModelConfig GetOfflineTtsModelConfig(
96 43
97 c.vits = GetOfflineTtsVitsModelConfig(o); 44 c.vits = GetOfflineTtsVitsModelConfig(o);
98 45
99 - if (o.Has("numThreads") && o.Get("numThreads").IsNumber()) {  
100 - c.num_threads = o.Get("numThreads").As<Napi::Number>().Int32Value();  
101 - } 46 + SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, num_threads);
102 47
103 if (o.Has("debug") && 48 if (o.Has("debug") &&
104 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) { 49 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) {
@@ -109,15 +54,7 @@ static SherpaOnnxOfflineTtsModelConfig GetOfflineTtsModelConfig( @@ -109,15 +54,7 @@ static SherpaOnnxOfflineTtsModelConfig GetOfflineTtsModelConfig(
109 } 54 }
110 } 55 }
111 56
112 - if (o.Has("provider") && o.Get("provider").IsString()) {  
113 - Napi::String provider = o.Get("provider").As<Napi::String>();  
114 - std::string s = provider.Utf8Value();  
115 - char *p = new char[s.size() + 1];  
116 - std::copy(s.begin(), s.end(), p);  
117 - p[s.size()] = 0;  
118 -  
119 - c.provider = p;  
120 - } 57 + SHERPA_ONNX_ASSIGN_ATTR_STR(provider, provider);
121 58
122 return c; 59 return c;
123 } 60 }
@@ -148,30 +85,9 @@ static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper( @@ -148,30 +85,9 @@ static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper(
148 85
149 c.model = GetOfflineTtsModelConfig(o); 86 c.model = GetOfflineTtsModelConfig(o);
150 87
151 - if (o.Has("ruleFsts") && o.Get("ruleFsts").IsString()) {  
152 - Napi::String rule_fsts = o.Get("ruleFsts").As<Napi::String>();  
153 - std::string s = rule_fsts.Utf8Value();  
154 - char *p = new char[s.size() + 1];  
155 - std::copy(s.begin(), s.end(), p);  
156 - p[s.size()] = 0;  
157 -  
158 - c.rule_fsts = p;  
159 - }  
160 -  
161 - if (o.Has("maxNumSentences") && o.Get("maxNumSentences").IsNumber()) {  
162 - c.max_num_sentences =  
163 - o.Get("maxNumSentences").As<Napi::Number>().Int32Value();  
164 - }  
165 -  
166 - if (o.Has("ruleFars") && o.Get("ruleFars").IsString()) {  
167 - Napi::String rule_fars = o.Get("ruleFars").As<Napi::String>();  
168 - std::string s = rule_fars.Utf8Value();  
169 - char *p = new char[s.size() + 1];  
170 - std::copy(s.begin(), s.end(), p);  
171 - p[s.size()] = 0;  
172 -  
173 - c.rule_fars = p;  
174 - } 88 + SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fsts, ruleFsts);
  89 + SHERPA_ONNX_ASSIGN_ATTR_INT32(max_num_sentences, maxNumSentences);
  90 + SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars);
175 91
176 SherpaOnnxOfflineTts *tts = SherpaOnnxCreateOfflineTts(&c); 92 SherpaOnnxOfflineTts *tts = SherpaOnnxCreateOfflineTts(&c);
177 93
@@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 -#include "napi.h" // NOLINT 7 +#include "macros.h" // NOLINT
  8 +#include "napi.h" // NOLINT
8 #include "sherpa-onnx/c-api/c-api.h" 9 #include "sherpa-onnx/c-api/c-api.h"
9 10
10 static SherpaOnnxSpokenLanguageIdentificationWhisperConfig 11 static SherpaOnnxSpokenLanguageIdentificationWhisperConfig
@@ -18,29 +19,9 @@ GetSpokenLanguageIdentificationWhisperConfig(Napi::Object obj) { @@ -18,29 +19,9 @@ GetSpokenLanguageIdentificationWhisperConfig(Napi::Object obj) {
18 19
19 Napi::Object o = obj.Get("whisper").As<Napi::Object>(); 20 Napi::Object o = obj.Get("whisper").As<Napi::Object>();
20 21
21 - if (o.Has("encoder") && o.Get("encoder").IsString()) {  
22 - Napi::String encoder = o.Get("encoder").As<Napi::String>();  
23 - std::string s = encoder.Utf8Value();  
24 - char *p = new char[s.size() + 1];  
25 - std::copy(s.begin(), s.end(), p);  
26 - p[s.size()] = 0;  
27 -  
28 - c.encoder = p;  
29 - }  
30 -  
31 - if (o.Has("decoder") && o.Get("decoder").IsString()) {  
32 - Napi::String decoder = o.Get("decoder").As<Napi::String>();  
33 - std::string s = decoder.Utf8Value();  
34 - char *p = new char[s.size() + 1];  
35 - std::copy(s.begin(), s.end(), p);  
36 - p[s.size()] = 0;  
37 -  
38 - c.decoder = p;  
39 - }  
40 -  
41 - if (o.Has("tailPaddings") && o.Get("tailPaddings").IsNumber()) {  
42 - c.tail_paddings = o.Get("tailPaddings").As<Napi::Number>().Int32Value();  
43 - } 22 + SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
  23 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
  24 + SHERPA_ONNX_ASSIGN_ATTR_INT32(tail_paddings, tailPaddings);
44 25
45 return c; 26 return c;
46 } 27 }
@@ -70,9 +51,7 @@ CreateSpokenLanguageIdentificationWrapper(const Napi::CallbackInfo &info) { @@ -70,9 +51,7 @@ CreateSpokenLanguageIdentificationWrapper(const Napi::CallbackInfo &info) {
70 memset(&c, 0, sizeof(c)); 51 memset(&c, 0, sizeof(c));
71 c.whisper = GetSpokenLanguageIdentificationWhisperConfig(o); 52 c.whisper = GetSpokenLanguageIdentificationWhisperConfig(o);
72 53
73 - if (o.Has("numThreads") && o.Get("numThreads").IsNumber()) {  
74 - c.num_threads = o.Get("numThreads").As<Napi::Number>().Int32Value();  
75 - } 54 + SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, numThreads);
76 55
77 if (o.Has("debug") && 56 if (o.Has("debug") &&
78 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) { 57 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) {
@@ -82,16 +61,7 @@ CreateSpokenLanguageIdentificationWrapper(const Napi::CallbackInfo &info) { @@ -82,16 +61,7 @@ CreateSpokenLanguageIdentificationWrapper(const Napi::CallbackInfo &info) {
82 c.debug = o.Get("debug").As<Napi::Number>().Int32Value(); 61 c.debug = o.Get("debug").As<Napi::Number>().Int32Value();
83 } 62 }
84 } 63 }
85 -  
86 - if (o.Has("provider") && o.Get("provider").IsString()) {  
87 - Napi::String provider = o.Get("provider").As<Napi::String>();  
88 - std::string s = provider.Utf8Value();  
89 - char *p = new char[s.size() + 1];  
90 - std::copy(s.begin(), s.end(), p);  
91 - p[s.size()] = 0;  
92 -  
93 - c.provider = p;  
94 - } 64 + SHERPA_ONNX_ASSIGN_ATTR_STR(provider, provider);
95 65
96 const SherpaOnnxSpokenLanguageIdentification *slid = 66 const SherpaOnnxSpokenLanguageIdentification *slid =
97 SherpaOnnxCreateSpokenLanguageIdentification(&c); 67 SherpaOnnxCreateSpokenLanguageIdentification(&c);
@@ -3,7 +3,8 @@ @@ -3,7 +3,8 @@
3 // Copyright (c) 2024 Xiaomi Corporation 3 // Copyright (c) 2024 Xiaomi Corporation
4 #include <sstream> 4 #include <sstream>
5 5
6 -#include "napi.h" // NOLINT 6 +#include "macros.h" // NOLINT
  7 +#include "napi.h" // NOLINT
7 #include "sherpa-onnx/c-api/c-api.h" 8 #include "sherpa-onnx/c-api/c-api.h"
8 /* 9 /*
9 { 10 {
@@ -14,26 +15,19 @@ @@ -14,26 +15,19 @@
14 }; 15 };
15 */ 16 */
16 SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj) { 17 SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj) {
17 - SherpaOnnxFeatureConfig config;  
18 - memset(&config, 0, sizeof(config)); 18 + SherpaOnnxFeatureConfig c;
  19 + memset(&c, 0, sizeof(c));
19 20
20 if (!obj.Has("featConfig") || !obj.Get("featConfig").IsObject()) { 21 if (!obj.Has("featConfig") || !obj.Get("featConfig").IsObject()) {
21 - return config; 22 + return c;
22 } 23 }
23 24
24 - Napi::Object featConfig = obj.Get("featConfig").As<Napi::Object>();  
25 -  
26 - if (featConfig.Has("sampleRate") && featConfig.Get("sampleRate").IsNumber()) {  
27 - config.sample_rate =  
28 - featConfig.Get("sampleRate").As<Napi::Number>().Int32Value();  
29 - } 25 + Napi::Object o = obj.Get("featConfig").As<Napi::Object>();
30 26
31 - if (featConfig.Has("featureDim") && featConfig.Get("featureDim").IsNumber()) {  
32 - config.feature_dim =  
33 - featConfig.Get("featureDim").As<Napi::Number>().Int32Value();  
34 - } 27 + SHERPA_ONNX_ASSIGN_ATTR_INT32(sample_rate, sampleRate);
  28 + SHERPA_ONNX_ASSIGN_ATTR_INT32(feature_dim, featureDim);
35 29
36 - return config; 30 + return c;
37 } 31 }
38 /* 32 /*
39 { 33 {
@@ -47,192 +41,103 @@ SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj) { @@ -47,192 +41,103 @@ SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj) {
47 41
48 static SherpaOnnxOnlineTransducerModelConfig GetOnlineTransducerModelConfig( 42 static SherpaOnnxOnlineTransducerModelConfig GetOnlineTransducerModelConfig(
49 Napi::Object obj) { 43 Napi::Object obj) {
50 - SherpaOnnxOnlineTransducerModelConfig config;  
51 - memset(&config, 0, sizeof(config)); 44 + SherpaOnnxOnlineTransducerModelConfig c;
  45 + memset(&c, 0, sizeof(c));
52 46
53 if (!obj.Has("transducer") || !obj.Get("transducer").IsObject()) { 47 if (!obj.Has("transducer") || !obj.Get("transducer").IsObject()) {
54 - return config; 48 + return c;
55 } 49 }
56 50
57 Napi::Object o = obj.Get("transducer").As<Napi::Object>(); 51 Napi::Object o = obj.Get("transducer").As<Napi::Object>();
58 52
59 - if (o.Has("encoder") && o.Get("encoder").IsString()) {  
60 - Napi::String encoder = o.Get("encoder").As<Napi::String>();  
61 - std::string s = encoder.Utf8Value();  
62 - char *p = new char[s.size() + 1];  
63 - std::copy(s.begin(), s.end(), p);  
64 - p[s.size()] = 0;  
65 -  
66 - config.encoder = p;  
67 - }  
68 -  
69 - if (o.Has("decoder") && o.Get("decoder").IsString()) {  
70 - Napi::String decoder = o.Get("decoder").As<Napi::String>();  
71 - std::string s = decoder.Utf8Value();  
72 - char *p = new char[s.size() + 1];  
73 - std::copy(s.begin(), s.end(), p);  
74 - p[s.size()] = 0;  
75 -  
76 - config.decoder = p;  
77 - }  
78 -  
79 - if (o.Has("joiner") && o.Get("joiner").IsString()) {  
80 - Napi::String joiner = o.Get("joiner").As<Napi::String>();  
81 - std::string s = joiner.Utf8Value();  
82 - char *p = new char[s.size() + 1];  
83 - std::copy(s.begin(), s.end(), p);  
84 - p[s.size()] = 0;  
85 -  
86 - config.joiner = p;  
87 - } 53 + SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
  54 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
  55 + SHERPA_ONNX_ASSIGN_ATTR_STR(joiner, joiner);
88 56
89 - return config; 57 + return c;
90 } 58 }
91 59
92 static SherpaOnnxOnlineZipformer2CtcModelConfig 60 static SherpaOnnxOnlineZipformer2CtcModelConfig
93 GetOnlineZipformer2CtcModelConfig(Napi::Object obj) { 61 GetOnlineZipformer2CtcModelConfig(Napi::Object obj) {
94 - SherpaOnnxOnlineZipformer2CtcModelConfig config;  
95 - memset(&config, 0, sizeof(config)); 62 + SherpaOnnxOnlineZipformer2CtcModelConfig c;
  63 + memset(&c, 0, sizeof(c));
96 64
97 if (!obj.Has("zipformer2Ctc") || !obj.Get("zipformer2Ctc").IsObject()) { 65 if (!obj.Has("zipformer2Ctc") || !obj.Get("zipformer2Ctc").IsObject()) {
98 - return config; 66 + return c;
99 } 67 }
100 68
101 Napi::Object o = obj.Get("zipformer2Ctc").As<Napi::Object>(); 69 Napi::Object o = obj.Get("zipformer2Ctc").As<Napi::Object>();
102 70
103 - if (o.Has("model") && o.Get("model").IsString()) {  
104 - Napi::String model = o.Get("model").As<Napi::String>();  
105 - std::string s = model.Utf8Value();  
106 - char *p = new char[s.size() + 1];  
107 - std::copy(s.begin(), s.end(), p);  
108 - p[s.size()] = 0;  
109 -  
110 - config.model = p;  
111 - } 71 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
112 72
113 - return config; 73 + return c;
114 } 74 }
115 75
116 static SherpaOnnxOnlineParaformerModelConfig GetOnlineParaformerModelConfig( 76 static SherpaOnnxOnlineParaformerModelConfig GetOnlineParaformerModelConfig(
117 Napi::Object obj) { 77 Napi::Object obj) {
118 - SherpaOnnxOnlineParaformerModelConfig config;  
119 - memset(&config, 0, sizeof(config)); 78 + SherpaOnnxOnlineParaformerModelConfig c;
  79 + memset(&c, 0, sizeof(c));
120 80
121 if (!obj.Has("paraformer") || !obj.Get("paraformer").IsObject()) { 81 if (!obj.Has("paraformer") || !obj.Get("paraformer").IsObject()) {
122 - return config; 82 + return c;
123 } 83 }
124 84
125 Napi::Object o = obj.Get("paraformer").As<Napi::Object>(); 85 Napi::Object o = obj.Get("paraformer").As<Napi::Object>();
126 86
127 - if (o.Has("encoder") && o.Get("encoder").IsString()) {  
128 - Napi::String encoder = o.Get("encoder").As<Napi::String>();  
129 - std::string s = encoder.Utf8Value();  
130 - char *p = new char[s.size() + 1];  
131 - std::copy(s.begin(), s.end(), p);  
132 - p[s.size()] = 0;  
133 -  
134 - config.encoder = p;  
135 - }  
136 -  
137 - if (o.Has("decoder") && o.Get("decoder").IsString()) {  
138 - Napi::String decoder = o.Get("decoder").As<Napi::String>();  
139 - std::string s = decoder.Utf8Value();  
140 - char *p = new char[s.size() + 1];  
141 - std::copy(s.begin(), s.end(), p);  
142 - p[s.size()] = 0; 87 + SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
  88 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
143 89
144 - config.decoder = p;  
145 - }  
146 - return config; 90 + return c;
147 } 91 }
148 92
149 static SherpaOnnxOnlineModelConfig GetOnlineModelConfig(Napi::Object obj) { 93 static SherpaOnnxOnlineModelConfig GetOnlineModelConfig(Napi::Object obj) {
150 - SherpaOnnxOnlineModelConfig config;  
151 - memset(&config, 0, sizeof(config)); 94 + SherpaOnnxOnlineModelConfig c;
  95 + memset(&c, 0, sizeof(c));
152 96
153 if (!obj.Has("modelConfig") || !obj.Get("modelConfig").IsObject()) { 97 if (!obj.Has("modelConfig") || !obj.Get("modelConfig").IsObject()) {
154 - return config; 98 + return c;
155 } 99 }
156 100
157 Napi::Object o = obj.Get("modelConfig").As<Napi::Object>(); 101 Napi::Object o = obj.Get("modelConfig").As<Napi::Object>();
158 102
159 - config.transducer = GetOnlineTransducerModelConfig(o);  
160 - config.paraformer = GetOnlineParaformerModelConfig(o);  
161 - config.zipformer2_ctc = GetOnlineZipformer2CtcModelConfig(o);  
162 -  
163 - if (o.Has("tokens") && o.Get("tokens").IsString()) {  
164 - Napi::String tokens = o.Get("tokens").As<Napi::String>();  
165 - std::string s = tokens.Utf8Value();  
166 - char *p = new char[s.size() + 1];  
167 - std::copy(s.begin(), s.end(), p);  
168 - p[s.size()] = 0; 103 + c.transducer = GetOnlineTransducerModelConfig(o);
  104 + c.paraformer = GetOnlineParaformerModelConfig(o);
  105 + c.zipformer2_ctc = GetOnlineZipformer2CtcModelConfig(o);
169 106
170 - config.tokens = p;  
171 - }  
172 -  
173 - if (o.Has("numThreads") && o.Get("numThreads").IsNumber()) {  
174 - config.num_threads = o.Get("numThreads").As<Napi::Number>().Int32Value();  
175 - }  
176 -  
177 - if (o.Has("provider") && o.Get("provider").IsString()) {  
178 - Napi::String provider = o.Get("provider").As<Napi::String>();  
179 - std::string s = provider.Utf8Value();  
180 - char *p = new char[s.size() + 1];  
181 - std::copy(s.begin(), s.end(), p);  
182 - p[s.size()] = 0;  
183 -  
184 - config.provider = p;  
185 - } 107 + SHERPA_ONNX_ASSIGN_ATTR_STR(tokens, tokens);
  108 + SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, numThreads);
  109 + SHERPA_ONNX_ASSIGN_ATTR_STR(provider, provider);
186 110
187 if (o.Has("debug") && 111 if (o.Has("debug") &&
188 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) { 112 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) {
189 if (o.Get("debug").IsBoolean()) { 113 if (o.Get("debug").IsBoolean()) {
190 - config.debug = o.Get("debug").As<Napi::Boolean>().Value(); 114 + c.debug = o.Get("debug").As<Napi::Boolean>().Value();
191 } else { 115 } else {
192 - config.debug = o.Get("debug").As<Napi::Number>().Int32Value(); 116 + c.debug = o.Get("debug").As<Napi::Number>().Int32Value();
193 } 117 }
194 } 118 }
195 119
196 - if (o.Has("modelType") && o.Get("modelType").IsString()) {  
197 - Napi::String model_type = o.Get("modelType").As<Napi::String>();  
198 - std::string s = model_type.Utf8Value();  
199 - char *p = new char[s.size() + 1];  
200 - std::copy(s.begin(), s.end(), p);  
201 - p[s.size()] = 0; 120 + SHERPA_ONNX_ASSIGN_ATTR_STR(model_type, modelType);
202 121
203 - config.model_type = p;  
204 - }  
205 -  
206 - return config; 122 + return c;
207 } 123 }
208 124
209 static SherpaOnnxOnlineCtcFstDecoderConfig GetCtcFstDecoderConfig( 125 static SherpaOnnxOnlineCtcFstDecoderConfig GetCtcFstDecoderConfig(
210 Napi::Object obj) { 126 Napi::Object obj) {
211 - SherpaOnnxOnlineCtcFstDecoderConfig config;  
212 - memset(&config, 0, sizeof(config)); 127 + SherpaOnnxOnlineCtcFstDecoderConfig c;
  128 + memset(&c, 0, sizeof(c));
213 129
214 if (!obj.Has("ctcFstDecoderConfig") || 130 if (!obj.Has("ctcFstDecoderConfig") ||
215 !obj.Get("ctcFstDecoderConfig").IsObject()) { 131 !obj.Get("ctcFstDecoderConfig").IsObject()) {
216 - return config; 132 + return c;
217 } 133 }
218 134
219 Napi::Object o = obj.Get("ctcFstDecoderConfig").As<Napi::Object>(); 135 Napi::Object o = obj.Get("ctcFstDecoderConfig").As<Napi::Object>();
220 136
221 - if (o.Has("graph") && o.Get("graph").IsString()) {  
222 - Napi::String graph = o.Get("graph").As<Napi::String>();  
223 - std::string s = graph.Utf8Value();  
224 - char *p = new char[s.size() + 1];  
225 - std::copy(s.begin(), s.end(), p);  
226 - p[s.size()] = 0; 137 + SHERPA_ONNX_ASSIGN_ATTR_STR(graph, graph);
  138 + SHERPA_ONNX_ASSIGN_ATTR_INT32(max_active, maxActive);
227 139
228 - config.graph = p;  
229 - }  
230 -  
231 - if (o.Has("maxActive") && o.Get("maxActive").IsNumber()) {  
232 - config.max_active = o.Get("maxActive").As<Napi::Number>().Int32Value();  
233 - }  
234 -  
235 - return config; 140 + return c;
236 } 141 }
237 142
238 static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( 143 static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
@@ -254,75 +159,36 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( @@ -254,75 +159,36 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
254 return {}; 159 return {};
255 } 160 }
256 161
257 - Napi::Object config = info[0].As<Napi::Object>(); 162 + Napi::Object o = info[0].As<Napi::Object>();
258 SherpaOnnxOnlineRecognizerConfig c; 163 SherpaOnnxOnlineRecognizerConfig c;
259 memset(&c, 0, sizeof(c)); 164 memset(&c, 0, sizeof(c));
260 - c.feat_config = GetFeatureConfig(config);  
261 - c.model_config = GetOnlineModelConfig(config); 165 + c.feat_config = GetFeatureConfig(o);
  166 + c.model_config = GetOnlineModelConfig(o);
262 167
263 - if (config.Has("decodingMethod") && config.Get("decodingMethod").IsString()) {  
264 - Napi::String decoding_method =  
265 - config.Get("decodingMethod").As<Napi::String>();  
266 - std::string s = decoding_method.Utf8Value();  
267 - char *p = new char[s.size() + 1];  
268 - std::copy(s.begin(), s.end(), p);  
269 - p[s.size()] = 0;  
270 -  
271 - c.decoding_method = p;  
272 - }  
273 -  
274 - if (config.Has("maxActivePaths") && config.Get("maxActivePaths").IsNumber()) {  
275 - c.max_active_paths =  
276 - config.Get("maxActivePaths").As<Napi::Number>().Int32Value();  
277 - } 168 + SHERPA_ONNX_ASSIGN_ATTR_STR(decoding_method, decodingMethod);
  169 + SHERPA_ONNX_ASSIGN_ATTR_INT32(max_active_paths, maxActivePaths);
278 170
279 // enableEndpoint can be either a boolean or an integer 171 // enableEndpoint can be either a boolean or an integer
280 - if (config.Has("enableEndpoint") &&  
281 - (config.Get("enableEndpoint").IsNumber() ||  
282 - config.Get("enableEndpoint").IsBoolean())) {  
283 - if (config.Get("enableEndpoint").IsNumber()) { 172 + if (o.Has("enableEndpoint") && (o.Get("enableEndpoint").IsNumber() ||
  173 + o.Get("enableEndpoint").IsBoolean())) {
  174 + if (o.Get("enableEndpoint").IsNumber()) {
284 c.enable_endpoint = 175 c.enable_endpoint =
285 - config.Get("enableEndpoint").As<Napi::Number>().Int32Value(); 176 + o.Get("enableEndpoint").As<Napi::Number>().Int32Value();
286 } else { 177 } else {
287 - c.enable_endpoint =  
288 - config.Get("enableEndpoint").As<Napi::Boolean>().Value(); 178 + c.enable_endpoint = o.Get("enableEndpoint").As<Napi::Boolean>().Value();
289 } 179 }
290 } 180 }
291 181
292 - if (config.Has("rule1MinTrailingSilence") &&  
293 - config.Get("rule1MinTrailingSilence").IsNumber()) {  
294 - c.rule1_min_trailing_silence =  
295 - config.Get("rule1MinTrailingSilence").As<Napi::Number>().FloatValue();  
296 - }  
297 -  
298 - if (config.Has("rule2MinTrailingSilence") &&  
299 - config.Get("rule2MinTrailingSilence").IsNumber()) {  
300 - c.rule2_min_trailing_silence =  
301 - config.Get("rule2MinTrailingSilence").As<Napi::Number>().FloatValue();  
302 - }  
303 -  
304 - if (config.Has("rule3MinUtteranceLength") &&  
305 - config.Get("rule3MinUtteranceLength").IsNumber()) {  
306 - c.rule3_min_utterance_length =  
307 - config.Get("rule3MinUtteranceLength").As<Napi::Number>().FloatValue();  
308 - }  
309 -  
310 - if (config.Has("hotwordsFile") && config.Get("hotwordsFile").IsString()) {  
311 - Napi::String hotwords_file = config.Get("hotwordsFile").As<Napi::String>();  
312 - std::string s = hotwords_file.Utf8Value();  
313 - char *p = new char[s.size() + 1];  
314 - std::copy(s.begin(), s.end(), p);  
315 - p[s.size()] = 0;  
316 -  
317 - c.hotwords_file = p;  
318 - }  
319 -  
320 - if (config.Has("hotwordsScore") && config.Get("hotwordsScore").IsNumber()) {  
321 - c.hotwords_score =  
322 - config.Get("hotwordsScore").As<Napi::Number>().FloatValue();  
323 - } 182 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(rule1_min_trailing_silence,
  183 + rule1MinTrailingSilence);
  184 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(rule2_min_trailing_silence,
  185 + rule2MinTrailingSilence);
  186 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(rule3_min_utterance_length,
  187 + rule3MinUtteranceLength);
  188 + SHERPA_ONNX_ASSIGN_ATTR_STR(hotwords_file, hotwordsFile);
  189 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(hotwords_score, hotwordsScore);
324 190
325 - c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(config); 191 + c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o);
326 192
327 SherpaOnnxOnlineRecognizer *recognizer = CreateOnlineRecognizer(&c); 193 SherpaOnnxOnlineRecognizer *recognizer = CreateOnlineRecognizer(&c);
328 194
@@ -4,7 +4,8 @@ @@ -4,7 +4,8 @@
4 4
5 #include <sstream> 5 #include <sstream>
6 6
7 -#include "napi.h" // NOLINT 7 +#include "macros.h" // NOLINT
  8 +#include "napi.h" // NOLINT
8 #include "sherpa-onnx/c-api/c-api.h" 9 #include "sherpa-onnx/c-api/c-api.h"
9 10
10 static Napi::External<SherpaOnnxCircularBuffer> CreateCircularBufferWrapper( 11 static Napi::External<SherpaOnnxCircularBuffer> CreateCircularBufferWrapper(
@@ -247,34 +248,11 @@ static SherpaOnnxSileroVadModelConfig GetSileroVadConfig( @@ -247,34 +248,11 @@ static SherpaOnnxSileroVadModelConfig GetSileroVadConfig(
247 } 248 }
248 249
249 Napi::Object o = obj.Get("sileroVad").As<Napi::Object>(); 250 Napi::Object o = obj.Get("sileroVad").As<Napi::Object>();
250 -  
251 - if (o.Has("model") && o.Get("model").IsString()) {  
252 - Napi::String model = o.Get("model").As<Napi::String>();  
253 - std::string s = model.Utf8Value();  
254 - char *p = new char[s.size() + 1];  
255 - std::copy(s.begin(), s.end(), p);  
256 - p[s.size()] = 0;  
257 -  
258 - c.model = p;  
259 - }  
260 -  
261 - if (o.Has("threshold") && o.Get("threshold").IsNumber()) {  
262 - c.threshold = o.Get("threshold").As<Napi::Number>().FloatValue();  
263 - }  
264 -  
265 - if (o.Has("minSilenceDuration") && o.Get("minSilenceDuration").IsNumber()) {  
266 - c.min_silence_duration =  
267 - o.Get("minSilenceDuration").As<Napi::Number>().FloatValue();  
268 - }  
269 -  
270 - if (o.Has("minSpeechDuration") && o.Get("minSpeechDuration").IsNumber()) {  
271 - c.min_speech_duration =  
272 - o.Get("minSpeechDuration").As<Napi::Number>().FloatValue();  
273 - }  
274 -  
275 - if (o.Has("windowSize") && o.Get("windowSize").IsNumber()) {  
276 - c.window_size = o.Get("windowSize").As<Napi::Number>().Int32Value();  
277 - } 251 + SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
  252 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(threshold, threshold);
  253 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(min_silence_duration, minSilenceDuration);
  254 + SHERPA_ONNX_ASSIGN_ATTR_FLOAT(min_speech_duration, minSpeechDuration);
  255 + SHERPA_ONNX_ASSIGN_ATTR_INT32(window_size, windowSize);
278 256
279 return c; 257 return c;
280 } 258 }
@@ -313,23 +291,9 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { @@ -313,23 +291,9 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) {
313 memset(&c, 0, sizeof(c)); 291 memset(&c, 0, sizeof(c));
314 c.silero_vad = GetSileroVadConfig(o); 292 c.silero_vad = GetSileroVadConfig(o);
315 293
316 - if (o.Has("sampleRate") && o.Get("sampleRate").IsNumber()) {  
317 - c.sample_rate = o.Get("sampleRate").As<Napi::Number>().Int32Value();  
318 - }  
319 -  
320 - if (o.Has("numThreads") && o.Get("numThreads").IsNumber()) {  
321 - c.num_threads = o.Get("numThreads").As<Napi::Number>().Int32Value();  
322 - }  
323 -  
324 - if (o.Has("provider") && o.Get("provider").IsString()) {  
325 - Napi::String provider = o.Get("provider").As<Napi::String>();  
326 - std::string s = provider.Utf8Value();  
327 - char *p = new char[s.size() + 1];  
328 - std::copy(s.begin(), s.end(), p);  
329 - p[s.size()] = 0;  
330 -  
331 - c.provider = p;  
332 - } 294 + SHERPA_ONNX_ASSIGN_ATTR_INT32(sample_rate, sampleRate);
  295 + SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, numThreads);
  296 + SHERPA_ONNX_ASSIGN_ATTR_STR(provider, provider);
333 297
334 if (o.Has("debug") && 298 if (o.Has("debug") &&
335 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) { 299 (o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) {