Skip to content

Commit

Permalink
Refactor node-addon-api to remove duplicate. (#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
csukuangfj authored May 14, 2024
1 parent 939fdd9 commit 0895b64
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 570 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/test-nodejs-addon-npm-aarch64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,19 @@ jobs:
cd /shared
d=nodejs-addon-examples
echo "dir: $d"
cd $d
npm install --verbose
git status
ls -lh
ls -lh node_modules
export DYLD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-darwin-x64:$DYLD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-darwin-arm64:$DYLD_LIBRARY_PATH
export LD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-linux-x64:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$PWD/node_modules/sherpa-onnx-linux-arm64:$LD_LIBRARY_PATH
cd ../
.github/scripts/test-nodejs-addon-npm.sh
37 changes: 37 additions & 0 deletions scripts/node-addon-api/src/macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// scripts/node-addon-api/src/macros.h
//
// Copyright (c) 2024 Xiaomi Corporation
#ifndef SCRIPTS_NODE_ADDON_API_SRC_MACROS_H_
#define SCRIPTS_NODE_ADDON_API_SRC_MACROS_H_

#include <algorithm>
#include <string>

#define SHERPA_ONNX_ASSIGN_ATTR_STR(c_name, js_name) \
do { \
if (o.Has(#js_name) && o.Get(#js_name).IsString()) { \
Napi::String _str = o.Get(#js_name).As<Napi::String>(); \
std::string s = _str.Utf8Value(); \
char *p = new char[s.size() + 1]; \
std::copy(s.begin(), s.end(), p); \
p[s.size()] = 0; \
\
c.c_name = p; \
} \
} while (0)

#define SHERPA_ONNX_ASSIGN_ATTR_INT32(c_name, js_name) \
do { \
if (o.Has(#js_name) && o.Get(#js_name).IsNumber()) { \
c.c_name = o.Get(#js_name).As<Napi::Number>().Int32Value(); \
} \
} while (0)

#define SHERPA_ONNX_ASSIGN_ATTR_FLOAT(c_name, js_name) \
do { \
if (o.Has(#js_name) && o.Get(#js_name).IsNumber()) { \
c.c_name = o.Get(#js_name).As<Napi::Number>().FloatValue(); \
} \
} while (0)

#endif // SCRIPTS_NODE_ADDON_API_SRC_MACROS_H_
231 changes: 42 additions & 189 deletions scripts/node-addon-api/src/non-streaming-asr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,180 +3,96 @@
// Copyright (c) 2024 Xiaomi Corporation
#include <sstream>

#include "napi.h" // NOLINT
#include "macros.h" // NOLINT
#include "napi.h" // NOLINT
#include "sherpa-onnx/c-api/c-api.h"

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

static SherpaOnnxOfflineTransducerModelConfig GetOfflineTransducerModelConfig(
Napi::Object obj) {
SherpaOnnxOfflineTransducerModelConfig config;
memset(&config, 0, sizeof(config));
SherpaOnnxOfflineTransducerModelConfig c;
memset(&c, 0, sizeof(c));

if (!obj.Has("transducer") || !obj.Get("transducer").IsObject()) {
return config;
return c;
}

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

if (o.Has("encoder") && o.Get("encoder").IsString()) {
Napi::String encoder = o.Get("encoder").As<Napi::String>();
std::string s = encoder.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.encoder = p;
}

if (o.Has("decoder") && o.Get("decoder").IsString()) {
Napi::String decoder = o.Get("decoder").As<Napi::String>();
std::string s = decoder.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.decoder = p;
}

if (o.Has("joiner") && o.Get("joiner").IsString()) {
Napi::String joiner = o.Get("joiner").As<Napi::String>();
std::string s = joiner.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;
SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
SHERPA_ONNX_ASSIGN_ATTR_STR(joiner, joiner);

config.joiner = p;
}

return config;
return c;
}

static SherpaOnnxOfflineParaformerModelConfig GetOfflineParaformerModelConfig(
Napi::Object obj) {
SherpaOnnxOfflineParaformerModelConfig config;
memset(&config, 0, sizeof(config));
SherpaOnnxOfflineParaformerModelConfig c;
memset(&c, 0, sizeof(c));

if (!obj.Has("paraformer") || !obj.Get("paraformer").IsObject()) {
return config;
return c;
}

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

if (o.Has("model") && o.Get("model").IsString()) {
Napi::String model = o.Get("model").As<Napi::String>();
std::string s = model.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.model = p;
}
SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);

return config;
return c;
}

static SherpaOnnxOfflineNemoEncDecCtcModelConfig GetOfflineNeMoCtcModelConfig(
Napi::Object obj) {
SherpaOnnxOfflineNemoEncDecCtcModelConfig config;
memset(&config, 0, sizeof(config));
SherpaOnnxOfflineNemoEncDecCtcModelConfig c;
memset(&c, 0, sizeof(c));

if (!obj.Has("nemoCtc") || !obj.Get("nemoCtc").IsObject()) {
return config;
return c;
}

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

if (o.Has("model") && o.Get("model").IsString()) {
Napi::String model = o.Get("model").As<Napi::String>();
std::string s = model.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.model = p;
}
SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);

return config;
return c;
}

static SherpaOnnxOfflineWhisperModelConfig GetOfflineWhisperModelConfig(
Napi::Object obj) {
SherpaOnnxOfflineWhisperModelConfig config;
memset(&config, 0, sizeof(config));
SherpaOnnxOfflineWhisperModelConfig c;
memset(&c, 0, sizeof(c));

if (!obj.Has("whisper") || !obj.Get("whisper").IsObject()) {
return config;
return c;
}

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

if (o.Has("encoder") && o.Get("encoder").IsString()) {
Napi::String encoder = o.Get("encoder").As<Napi::String>();
std::string s = encoder.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.encoder = p;
}

if (o.Has("decoder") && o.Get("decoder").IsString()) {
Napi::String decoder = o.Get("decoder").As<Napi::String>();
std::string s = decoder.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.decoder = p;
}

if (o.Has("language") && o.Get("language").IsString()) {
Napi::String language = o.Get("language").As<Napi::String>();
std::string s = language.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.language = p;
}

if (o.Has("task") && o.Get("task").IsString()) {
Napi::String task = o.Get("task").As<Napi::String>();
std::string s = task.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.task = p;
}
SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
SHERPA_ONNX_ASSIGN_ATTR_STR(language, language);
SHERPA_ONNX_ASSIGN_ATTR_STR(task, languagek);

return config;
return c;
}

static SherpaOnnxOfflineTdnnModelConfig GetOfflineTdnnModelConfig(
Napi::Object obj) {
SherpaOnnxOfflineTdnnModelConfig config;
memset(&config, 0, sizeof(config));
SherpaOnnxOfflineTdnnModelConfig c;
memset(&c, 0, sizeof(c));

if (!obj.Has("tdnn") || !obj.Get("tdnn").IsObject()) {
return config;
return c;
}

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

if (o.Has("model") && o.Get("model").IsString()) {
Napi::String model = o.Get("model").As<Napi::String>();
std::string s = model.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

config.model = p;
}
SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);

return config;
return c;
}

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

if (o.Has("tokens") && o.Get("tokens").IsString()) {
Napi::String tokens = o.Get("tokens").As<Napi::String>();
std::string s = tokens.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

c.tokens = p;
}

if (o.Has("numThreads") && o.Get("numThreads").IsNumber()) {
c.num_threads = o.Get("numThreads").As<Napi::Number>().Int32Value();
}
SHERPA_ONNX_ASSIGN_ATTR_STR(tokens, tokens);
SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, numThreads);

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

if (o.Has("provider") && o.Get("provider").IsString()) {
Napi::String provider = o.Get("provider").As<Napi::String>();
std::string s = provider.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

c.provider = p;
}

if (o.Has("modelType") && o.Get("modelType").IsString()) {
Napi::String model_type = o.Get("modelType").As<Napi::String>();
std::string s = model_type.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

c.model_type = p;
}
SHERPA_ONNX_ASSIGN_ATTR_STR(provider, provider);
SHERPA_ONNX_ASSIGN_ATTR_STR(model_type, modelType);

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

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

if (o.Has("model") && o.Get("model").IsString()) {
Napi::String model = o.Get("model").As<Napi::String>();
std::string s = model.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

c.model = p;
}

if (o.Has("scale") && o.Get("scale").IsNumber()) {
c.scale = o.Get("scale").As<Napi::Number>().FloatValue();
}
SHERPA_ONNX_ASSIGN_ATTR_STR(model, model);
SHERPA_ONNX_ASSIGN_ATTR_FLOAT(scale, scale);

return c;
}
Expand Down Expand Up @@ -295,34 +172,10 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) {
c.model_config = GetOfflineModelConfig(o);
c.lm_config = GetOfflineLMConfig(o);

if (o.Has("decodingMethod") && o.Get("decodingMethod").IsString()) {
Napi::String decoding_method = o.Get("decodingMethod").As<Napi::String>();
std::string s = decoding_method.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

c.decoding_method = p;
}

if (o.Has("maxActivePaths") && o.Get("maxActivePaths").IsNumber()) {
c.max_active_paths =
o.Get("maxActivePaths").As<Napi::Number>().Int32Value();
}

if (o.Has("hotwordsFile") && o.Get("hotwordsFile").IsString()) {
Napi::String hotwords_file = o.Get("hotwordsFile").As<Napi::String>();
std::string s = hotwords_file.Utf8Value();
char *p = new char[s.size() + 1];
std::copy(s.begin(), s.end(), p);
p[s.size()] = 0;

c.hotwords_file = p;
}

if (o.Has("hotwordsScore") && o.Get("hotwordsScore").IsNumber()) {
c.hotwords_score = o.Get("hotwordsScore").As<Napi::Number>().FloatValue();
}
SHERPA_ONNX_ASSIGN_ATTR_STR(decoding_method, decodingMethod);
SHERPA_ONNX_ASSIGN_ATTR_INT32(max_active_paths, maxActivePaths);
SHERPA_ONNX_ASSIGN_ATTR_STR(hotwords_file, hotwordsFile);
SHERPA_ONNX_ASSIGN_ATTR_FLOAT(hotwords_score, hotwordsScore);

SherpaOnnxOfflineRecognizer *recognizer = CreateOfflineRecognizer(&c);

Expand Down
Loading

0 comments on commit 0895b64

Please sign in to comment.