Skip to content

Commit 0895b64

Browse files
authored
Refactor node-addon-api to remove duplicate. (#873)
1 parent 939fdd9 commit 0895b64

File tree

7 files changed

+191
-570
lines changed

7 files changed

+191
-570
lines changed

.github/workflows/test-nodejs-addon-npm-aarch64.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,19 @@ jobs:
7777
7878
cd /shared
7979
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+
8095
.github/scripts/test-nodejs-addon-npm.sh

scripts/node-addon-api/src/macros.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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_

scripts/node-addon-api/src/non-streaming-asr.cc

+42-189
Original file line numberDiff line numberDiff line change
@@ -3,180 +3,96 @@
33
// Copyright (c) 2024 Xiaomi Corporation
44
#include <sstream>
55

6-
#include "napi.h" // NOLINT
6+
#include "macros.h" // NOLINT
7+
#include "napi.h" // NOLINT
78
#include "sherpa-onnx/c-api/c-api.h"
89

910
// defined in ./streaming-asr.cc
1011
SherpaOnnxFeatureConfig GetFeatureConfig(Napi::Object obj);
1112

1213
static SherpaOnnxOfflineTransducerModelConfig GetOfflineTransducerModelConfig(
1314
Napi::Object obj) {
14-
SherpaOnnxOfflineTransducerModelConfig config;
15-
memset(&config, 0, sizeof(config));
15+
SherpaOnnxOfflineTransducerModelConfig c;
16+
memset(&c, 0, sizeof(c));
1617

1718
if (!obj.Has("transducer") || !obj.Get("transducer").IsObject()) {
18-
return config;
19+
return c;
1920
}
2021

2122
Napi::Object o = obj.Get("transducer").As<Napi::Object>();
2223

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);
4927

50-
config.joiner = p;
51-
}
52-
53-
return config;
28+
return c;
5429
}
5530

5631
static SherpaOnnxOfflineParaformerModelConfig GetOfflineParaformerModelConfig(
5732
Napi::Object obj) {
58-
SherpaOnnxOfflineParaformerModelConfig config;
59-
memset(&config, 0, sizeof(config));
33+
SherpaOnnxOfflineParaformerModelConfig c;
34+
memset(&c, 0, sizeof(c));
6035

6136
if (!obj.Has("paraformer") || !obj.Get("paraformer").IsObject()) {
62-
return config;
37+
return c;
6338
}
6439

6540
Napi::Object o = obj.Get("paraformer").As<Napi::Object>();
6641

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);
7643

77-
return config;
44+
return c;
7845
}
7946

8047
static SherpaOnnxOfflineNemoEncDecCtcModelConfig GetOfflineNeMoCtcModelConfig(
8148
Napi::Object obj) {
82-
SherpaOnnxOfflineNemoEncDecCtcModelConfig config;
83-
memset(&config, 0, sizeof(config));
49+
SherpaOnnxOfflineNemoEncDecCtcModelConfig c;
50+
memset(&c, 0, sizeof(c));
8451

8552
if (!obj.Has("nemoCtc") || !obj.Get("nemoCtc").IsObject()) {
86-
return config;
53+
return c;
8754
}
8855

8956
Napi::Object o = obj.Get("nemoCtc").As<Napi::Object>();
9057

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);
10059

101-
return config;
60+
return c;
10261
}
10362

10463
static SherpaOnnxOfflineWhisperModelConfig GetOfflineWhisperModelConfig(
10564
Napi::Object obj) {
106-
SherpaOnnxOfflineWhisperModelConfig config;
107-
memset(&config, 0, sizeof(config));
65+
SherpaOnnxOfflineWhisperModelConfig c;
66+
memset(&c, 0, sizeof(c));
10867

10968
if (!obj.Has("whisper") || !obj.Get("whisper").IsObject()) {
110-
return config;
69+
return c;
11170
}
11271

11372
Napi::Object o = obj.Get("whisper").As<Napi::Object>();
11473

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);
15478

155-
return config;
79+
return c;
15680
}
15781

15882
static SherpaOnnxOfflineTdnnModelConfig GetOfflineTdnnModelConfig(
15983
Napi::Object obj) {
160-
SherpaOnnxOfflineTdnnModelConfig config;
161-
memset(&config, 0, sizeof(config));
84+
SherpaOnnxOfflineTdnnModelConfig c;
85+
memset(&c, 0, sizeof(c));
16286

16387
if (!obj.Has("tdnn") || !obj.Get("tdnn").IsObject()) {
164-
return config;
88+
return c;
16589
}
16690

16791
Napi::Object o = obj.Get("tdnn").As<Napi::Object>();
16892

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);
17894

179-
return config;
95+
return c;
18096
}
18197

18298
static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
@@ -195,19 +111,8 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
195111
c.whisper = GetOfflineWhisperModelConfig(o);
196112
c.tdnn = GetOfflineTdnnModelConfig(o);
197113

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);
211116

212117
if (o.Has("debug") &&
213118
(o.Get("debug").IsNumber() || o.Get("debug").IsBoolean())) {
@@ -218,25 +123,8 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
218123
}
219124
}
220125

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);
240128

241129
return c;
242130
}
@@ -251,19 +139,8 @@ static SherpaOnnxOfflineLMConfig GetOfflineLMConfig(Napi::Object obj) {
251139

252140
Napi::Object o = obj.Get("lmConfig").As<Napi::Object>();
253141

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);
267144

268145
return c;
269146
}
@@ -295,34 +172,10 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) {
295172
c.model_config = GetOfflineModelConfig(o);
296173
c.lm_config = GetOfflineLMConfig(o);
297174

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);
326179

327180
SherpaOnnxOfflineRecognizer *recognizer = CreateOfflineRecognizer(&c);
328181

0 commit comments

Comments
 (0)