Add keyword spotter C API for HarmonyOS (#1769)
This commit is contained in:
@@ -16,6 +16,16 @@ SherpaOnnxOnlineModelConfig GetOnlineModelConfig(Napi::Object obj);
|
||||
static Napi::External<SherpaOnnxKeywordSpotter> CreateKeywordSpotterWrapper(
|
||||
const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
#if __OHOS__
|
||||
if (info.Length() != 2) {
|
||||
std::ostringstream os;
|
||||
os << "Expect only 2 arguments. Given: " << info.Length();
|
||||
|
||||
Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException();
|
||||
|
||||
return {};
|
||||
}
|
||||
#else
|
||||
if (info.Length() != 1) {
|
||||
std::ostringstream os;
|
||||
os << "Expect only 1 argument. Given: " << info.Length();
|
||||
@@ -24,7 +34,7 @@ static Napi::External<SherpaOnnxKeywordSpotter> CreateKeywordSpotterWrapper(
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
#endif
|
||||
if (!info[0].IsObject()) {
|
||||
Napi::TypeError::New(env, "Expect an object as the argument")
|
||||
.ThrowAsJavaScriptException();
|
||||
@@ -46,7 +56,18 @@ static Napi::External<SherpaOnnxKeywordSpotter> CreateKeywordSpotterWrapper(
|
||||
SHERPA_ONNX_ASSIGN_ATTR_STR(keywords_buf, keywordsBuf);
|
||||
SHERPA_ONNX_ASSIGN_ATTR_INT32(keywords_buf_size, keywordsBufSize);
|
||||
|
||||
#if __OHOS__
|
||||
std::unique_ptr<NativeResourceManager,
|
||||
decltype(&OH_ResourceManager_ReleaseNativeResourceManager)>
|
||||
mgr(OH_ResourceManager_InitNativeResourceManager(env, info[1]),
|
||||
&OH_ResourceManager_ReleaseNativeResourceManager);
|
||||
|
||||
const SherpaOnnxKeywordSpotter *kws =
|
||||
SherpaOnnxCreateKeywordSpotterOHOS(&c, mgr.get());
|
||||
#else
|
||||
const SherpaOnnxKeywordSpotter *kws = SherpaOnnxCreateKeywordSpotter(&c);
|
||||
#endif
|
||||
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.encoder);
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.decoder);
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.joiner);
|
||||
@@ -79,9 +100,9 @@ static Napi::External<SherpaOnnxKeywordSpotter> CreateKeywordSpotterWrapper(
|
||||
static Napi::External<SherpaOnnxOnlineStream> CreateKeywordStreamWrapper(
|
||||
const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
if (info.Length() != 1) {
|
||||
if (info.Length() != 1 && info.Length() != 2) {
|
||||
std::ostringstream os;
|
||||
os << "Expect only 1 argument. Given: " << info.Length();
|
||||
os << "Expect only 1 or 2 arguments. Given: " << info.Length();
|
||||
|
||||
Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException();
|
||||
|
||||
@@ -96,10 +117,24 @@ static Napi::External<SherpaOnnxOnlineStream> CreateKeywordStreamWrapper(
|
||||
return {};
|
||||
}
|
||||
|
||||
if (info.Length() == 2 && !info[1].IsString()) {
|
||||
std::ostringstream os;
|
||||
os << "Argument 2 should be a string.";
|
||||
Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException();
|
||||
return {};
|
||||
}
|
||||
|
||||
const SherpaOnnxKeywordSpotter *kws =
|
||||
info[0].As<Napi::External<SherpaOnnxKeywordSpotter>>().Data();
|
||||
|
||||
const SherpaOnnxOnlineStream *stream = SherpaOnnxCreateKeywordStream(kws);
|
||||
const SherpaOnnxOnlineStream *stream;
|
||||
if (info.Length() == 1) {
|
||||
stream = SherpaOnnxCreateKeywordStream(kws);
|
||||
} else {
|
||||
Napi::String js_keywords = info[1].As<Napi::String>();
|
||||
std::string keywords = js_keywords.Utf8Value();
|
||||
stream = SherpaOnnxCreateKeywordStreamWithKeywords(kws, keywords.c_str());
|
||||
}
|
||||
|
||||
return Napi::External<SherpaOnnxOnlineStream>::New(
|
||||
env, const_cast<SherpaOnnxOnlineStream *>(stream),
|
||||
|
||||
@@ -678,7 +678,7 @@ struct SherpaOnnxKeywordSpotter {
|
||||
std::unique_ptr<sherpa_onnx::KeywordSpotter> impl;
|
||||
};
|
||||
|
||||
const SherpaOnnxKeywordSpotter *SherpaOnnxCreateKeywordSpotter(
|
||||
static sherpa_onnx::KeywordSpotterConfig GetKeywordSpotterConfig(
|
||||
const SherpaOnnxKeywordSpotterConfig *config) {
|
||||
sherpa_onnx::KeywordSpotterConfig spotter_config;
|
||||
|
||||
@@ -739,10 +739,20 @@ const SherpaOnnxKeywordSpotter *SherpaOnnxCreateKeywordSpotter(
|
||||
std::string(config->keywords_buf, config->keywords_buf_size);
|
||||
}
|
||||
|
||||
if (config->model_config.debug) {
|
||||
if (spotter_config.model_config.debug) {
|
||||
#if OHOS
|
||||
SHERPA_ONNX_LOGE("%{public}s\n", spotter_config.ToString().c_str());
|
||||
#else
|
||||
SHERPA_ONNX_LOGE("%s\n", spotter_config.ToString().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
return spotter_config;
|
||||
}
|
||||
|
||||
const SherpaOnnxKeywordSpotter *SherpaOnnxCreateKeywordSpotter(
|
||||
const SherpaOnnxKeywordSpotterConfig *config) {
|
||||
auto spotter_config = GetKeywordSpotterConfig(config);
|
||||
if (!spotter_config.Validate()) {
|
||||
SHERPA_ONNX_LOGE("Errors in config!");
|
||||
return nullptr;
|
||||
@@ -2272,6 +2282,22 @@ SherpaOnnxCreateSpeakerEmbeddingExtractorOHOS(
|
||||
return p;
|
||||
}
|
||||
|
||||
const SherpaOnnxKeywordSpotter *SherpaOnnxCreateKeywordSpotterOHOS(
|
||||
const SherpaOnnxKeywordSpotterConfig *config, NativeResourceManager *mgr) {
|
||||
if (!mgr) {
|
||||
return SherpaOnnxCreateKeywordSpotter(config);
|
||||
}
|
||||
|
||||
auto spotter_config = GetKeywordSpotterConfig(config);
|
||||
|
||||
SherpaOnnxKeywordSpotter *spotter = new SherpaOnnxKeywordSpotter;
|
||||
|
||||
spotter->impl =
|
||||
std::make_unique<sherpa_onnx::KeywordSpotter>(mgr, spotter_config);
|
||||
|
||||
return spotter;
|
||||
}
|
||||
|
||||
#if SHERPA_ONNX_ENABLE_TTS == 1
|
||||
const SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTtsOHOS(
|
||||
const SherpaOnnxOfflineTtsConfig *config, NativeResourceManager *mgr) {
|
||||
|
||||
@@ -1645,6 +1645,10 @@ SherpaOnnxCreateSpeakerEmbeddingExtractorOHOS(
|
||||
const SherpaOnnxSpeakerEmbeddingExtractorConfig *config,
|
||||
NativeResourceManager *mgr);
|
||||
|
||||
SHERPA_ONNX_API const SherpaOnnxKeywordSpotter *
|
||||
SherpaOnnxCreateKeywordSpotterOHOS(const SherpaOnnxKeywordSpotterConfig *config,
|
||||
NativeResourceManager *mgr);
|
||||
|
||||
SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarization *
|
||||
SherpaOnnxCreateOfflineSpeakerDiarizationOHOS(
|
||||
const SherpaOnnxOfflineSpeakerDiarizationConfig *config,
|
||||
|
||||
@@ -6,6 +6,15 @@
|
||||
|
||||
#include "sherpa-onnx/csrc/keyword-spotter-transducer-impl.h"
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
#include "android/asset_manager.h"
|
||||
#include "android/asset_manager_jni.h"
|
||||
#endif
|
||||
|
||||
#if __OHOS__
|
||||
#include "rawfile/raw_file_manager.h"
|
||||
#endif
|
||||
|
||||
namespace sherpa_onnx {
|
||||
|
||||
std::unique_ptr<KeywordSpotterImpl> KeywordSpotterImpl::Create(
|
||||
@@ -18,9 +27,9 @@ std::unique_ptr<KeywordSpotterImpl> KeywordSpotterImpl::Create(
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
template <typename Manager>
|
||||
std::unique_ptr<KeywordSpotterImpl> KeywordSpotterImpl::Create(
|
||||
AAssetManager *mgr, const KeywordSpotterConfig &config) {
|
||||
Manager *mgr, const KeywordSpotterConfig &config) {
|
||||
if (!config.model_config.transducer.encoder.empty()) {
|
||||
return std::make_unique<KeywordSpotterTransducerImpl>(mgr, config);
|
||||
}
|
||||
@@ -28,6 +37,15 @@ std::unique_ptr<KeywordSpotterImpl> KeywordSpotterImpl::Create(
|
||||
SHERPA_ONNX_LOGE("Please specify a model");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
template std::unique_ptr<KeywordSpotterImpl> KeywordSpotterImpl::Create(
|
||||
AAssetManager *mgr, const KeywordSpotterConfig &config);
|
||||
#endif
|
||||
|
||||
#if __OHOS__
|
||||
template std::unique_ptr<KeywordSpotterImpl> KeywordSpotterImpl::Create(
|
||||
NativeResourceManager *mgr, const KeywordSpotterConfig &config);
|
||||
#endif
|
||||
|
||||
} // namespace sherpa_onnx
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
#include "android/asset_manager.h"
|
||||
#include "android/asset_manager_jni.h"
|
||||
#endif
|
||||
|
||||
#include "sherpa-onnx/csrc/keyword-spotter.h"
|
||||
#include "sherpa-onnx/csrc/online-stream.h"
|
||||
|
||||
@@ -24,10 +19,9 @@ class KeywordSpotterImpl {
|
||||
static std::unique_ptr<KeywordSpotterImpl> Create(
|
||||
const KeywordSpotterConfig &config);
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
template <typename Manager>
|
||||
static std::unique_ptr<KeywordSpotterImpl> Create(
|
||||
AAssetManager *mgr, const KeywordSpotterConfig &config);
|
||||
#endif
|
||||
Manager *mgr, const KeywordSpotterConfig &config);
|
||||
|
||||
virtual ~KeywordSpotterImpl() = default;
|
||||
|
||||
|
||||
@@ -9,16 +9,10 @@
|
||||
#include <memory>
|
||||
#include <regex> // NOLINT
|
||||
#include <string>
|
||||
#include <strstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
#include <strstream>
|
||||
|
||||
#include "android/asset_manager.h"
|
||||
#include "android/asset_manager_jni.h"
|
||||
#endif
|
||||
|
||||
#include "sherpa-onnx/csrc/file-utils.h"
|
||||
#include "sherpa-onnx/csrc/keyword-spotter-impl.h"
|
||||
#include "sherpa-onnx/csrc/keyword-spotter.h"
|
||||
@@ -91,9 +85,8 @@ class KeywordSpotterTransducerImpl : public KeywordSpotterImpl {
|
||||
unk_id_);
|
||||
}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
KeywordSpotterTransducerImpl(AAssetManager *mgr,
|
||||
const KeywordSpotterConfig &config)
|
||||
template <typename Manager>
|
||||
KeywordSpotterTransducerImpl(Manager *mgr, const KeywordSpotterConfig &config)
|
||||
: config_(config),
|
||||
model_(OnlineTransducerModel::Create(mgr, config.model_config)),
|
||||
sym_(mgr, config.model_config.tokens) {
|
||||
@@ -109,7 +102,6 @@ class KeywordSpotterTransducerImpl : public KeywordSpotterImpl {
|
||||
model_.get(), config_.max_active_paths, config_.num_trailing_blanks,
|
||||
unk_id_);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<OnlineStream> CreateStream() const override {
|
||||
auto stream =
|
||||
@@ -130,7 +122,11 @@ class KeywordSpotterTransducerImpl : public KeywordSpotterImpl {
|
||||
|
||||
if (!EncodeKeywords(is, sym_, ¤t_ids, ¤t_kws, ¤t_scores,
|
||||
¤t_thresholds)) {
|
||||
#if __OHOS__
|
||||
SHERPA_ONNX_LOGE("Encode keywords %{public}s failed.", keywords.c_str());
|
||||
#else
|
||||
SHERPA_ONNX_LOGE("Encode keywords %s failed.", keywords.c_str());
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -306,16 +302,21 @@ class KeywordSpotterTransducerImpl : public KeywordSpotterImpl {
|
||||
// each line in keywords_file contains space-separated words
|
||||
std::ifstream is(config_.keywords_file);
|
||||
if (!is) {
|
||||
#if __OHOS__
|
||||
SHERPA_ONNX_LOGE("Open keywords file failed: %{public}s",
|
||||
config_.keywords_file.c_str());
|
||||
#else
|
||||
SHERPA_ONNX_LOGE("Open keywords file failed: %s",
|
||||
config_.keywords_file.c_str());
|
||||
#endif
|
||||
exit(-1);
|
||||
}
|
||||
InitKeywords(is);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
void InitKeywords(AAssetManager *mgr) {
|
||||
template <typename Manager>
|
||||
void InitKeywords(Manager *mgr) {
|
||||
// each line in keywords_file contains space-separated words
|
||||
|
||||
auto buf = ReadFile(mgr, config_.keywords_file);
|
||||
@@ -323,13 +324,17 @@ class KeywordSpotterTransducerImpl : public KeywordSpotterImpl {
|
||||
std::istrstream is(buf.data(), buf.size());
|
||||
|
||||
if (!is) {
|
||||
#if __OHOS__
|
||||
SHERPA_ONNX_LOGE("Open keywords file failed: %{public}s",
|
||||
config_.keywords_file.c_str());
|
||||
#else
|
||||
SHERPA_ONNX_LOGE("Open keywords file failed: %s",
|
||||
config_.keywords_file.c_str());
|
||||
#endif
|
||||
exit(-1);
|
||||
}
|
||||
InitKeywords(is);
|
||||
}
|
||||
#endif
|
||||
|
||||
void InitKeywordsFromBufStr() {
|
||||
// keywords_buf's content is supposed to be same as the keywords_file's
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
#include "android/asset_manager.h"
|
||||
#include "android/asset_manager_jni.h"
|
||||
#endif
|
||||
|
||||
#if __OHOS__
|
||||
#include "rawfile/raw_file_manager.h"
|
||||
#endif
|
||||
|
||||
#include "sherpa-onnx/csrc/keyword-spotter-impl.h"
|
||||
|
||||
namespace sherpa_onnx {
|
||||
@@ -136,11 +145,9 @@ std::string KeywordSpotterConfig::ToString() const {
|
||||
KeywordSpotter::KeywordSpotter(const KeywordSpotterConfig &config)
|
||||
: impl_(KeywordSpotterImpl::Create(config)) {}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
KeywordSpotter::KeywordSpotter(AAssetManager *mgr,
|
||||
const KeywordSpotterConfig &config)
|
||||
template <typename Manager>
|
||||
KeywordSpotter::KeywordSpotter(Manager *mgr, const KeywordSpotterConfig &config)
|
||||
: impl_(KeywordSpotterImpl::Create(mgr, config)) {}
|
||||
#endif
|
||||
|
||||
KeywordSpotter::~KeywordSpotter() = default;
|
||||
|
||||
@@ -167,4 +174,14 @@ KeywordResult KeywordSpotter::GetResult(OnlineStream *s) const {
|
||||
return impl_->GetResult(s);
|
||||
}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
template KeywordSpotter::KeywordSpotter(AAssetManager *mgr,
|
||||
const KeywordSpotterConfig &config);
|
||||
#endif
|
||||
|
||||
#if __OHOS__
|
||||
template KeywordSpotter::KeywordSpotter(NativeResourceManager *mgr,
|
||||
const KeywordSpotterConfig &config);
|
||||
#endif
|
||||
|
||||
} // namespace sherpa_onnx
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
#include "android/asset_manager.h"
|
||||
#include "android/asset_manager_jni.h"
|
||||
#endif
|
||||
|
||||
#include "sherpa-onnx/csrc/features.h"
|
||||
#include "sherpa-onnx/csrc/online-model-config.h"
|
||||
#include "sherpa-onnx/csrc/online-stream.h"
|
||||
@@ -101,9 +96,8 @@ class KeywordSpotter {
|
||||
public:
|
||||
explicit KeywordSpotter(const KeywordSpotterConfig &config);
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
KeywordSpotter(AAssetManager *mgr, const KeywordSpotterConfig &config);
|
||||
#endif
|
||||
template <typename Manager>
|
||||
KeywordSpotter(Manager *mgr, const KeywordSpotterConfig &config);
|
||||
|
||||
~KeywordSpotter();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user