Add on-device tex-to-speech (TTS) demo for HarmonyOS (#1590)
This commit is contained in:
@@ -6,11 +6,21 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <regex> // NOLINT
|
||||
#include <strstream>
|
||||
#include <utility>
|
||||
#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 "cppjieba/Jieba.hpp"
|
||||
#include "sherpa-onnx/csrc/file-utils.h"
|
||||
#include "sherpa-onnx/csrc/macros.h"
|
||||
#include "sherpa-onnx/csrc/onnx-utils.h"
|
||||
#include "sherpa-onnx/csrc/symbol-table.h"
|
||||
#include "sherpa-onnx/csrc/text-utils.h"
|
||||
|
||||
@@ -62,6 +72,60 @@ class MeloTtsLexicon::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Manager>
|
||||
Impl(Manager *mgr, const std::string &lexicon, const std::string &tokens,
|
||||
const std::string &dict_dir,
|
||||
const OfflineTtsVitsModelMetaData &meta_data, bool debug)
|
||||
: meta_data_(meta_data), debug_(debug) {
|
||||
std::string dict = dict_dir + "/jieba.dict.utf8";
|
||||
std::string hmm = dict_dir + "/hmm_model.utf8";
|
||||
std::string user_dict = dict_dir + "/user.dict.utf8";
|
||||
std::string idf = dict_dir + "/idf.utf8";
|
||||
std::string stop_word = dict_dir + "/stop_words.utf8";
|
||||
|
||||
AssertFileExists(dict);
|
||||
AssertFileExists(hmm);
|
||||
AssertFileExists(user_dict);
|
||||
AssertFileExists(idf);
|
||||
AssertFileExists(stop_word);
|
||||
|
||||
jieba_ =
|
||||
std::make_unique<cppjieba::Jieba>(dict, hmm, user_dict, idf, stop_word);
|
||||
|
||||
{
|
||||
auto buf = ReadFile(mgr, tokens);
|
||||
|
||||
std::istrstream is(buf.data(), buf.size());
|
||||
InitTokens(is);
|
||||
}
|
||||
|
||||
{
|
||||
auto buf = ReadFile(mgr, lexicon);
|
||||
|
||||
std::istrstream is(buf.data(), buf.size());
|
||||
InitLexicon(is);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Manager>
|
||||
Impl(Manager *mgr, const std::string &lexicon, const std::string &tokens,
|
||||
const OfflineTtsVitsModelMetaData &meta_data, bool debug)
|
||||
: meta_data_(meta_data), debug_(debug) {
|
||||
{
|
||||
auto buf = ReadFile(mgr, tokens);
|
||||
|
||||
std::istrstream is(buf.data(), buf.size());
|
||||
InitTokens(is);
|
||||
}
|
||||
|
||||
{
|
||||
auto buf = ReadFile(mgr, lexicon);
|
||||
|
||||
std::istrstream is(buf.data(), buf.size());
|
||||
InitLexicon(is);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<TokenIDs> ConvertTextToTokenIds(const std::string &_text) const {
|
||||
std::string text = ToLowerCase(_text);
|
||||
// see
|
||||
@@ -84,17 +148,24 @@ class MeloTtsLexicon::Impl {
|
||||
jieba_->Cut(text, words, is_hmm);
|
||||
|
||||
if (debug_) {
|
||||
SHERPA_ONNX_LOGE("input text: %s", text.c_str());
|
||||
SHERPA_ONNX_LOGE("after replacing punctuations: %s", s.c_str());
|
||||
|
||||
std::ostringstream os;
|
||||
std::string sep = "";
|
||||
for (const auto &w : words) {
|
||||
os << sep << w;
|
||||
sep = "_";
|
||||
}
|
||||
#if __OHOS__
|
||||
SHERPA_ONNX_LOGE("input text: %{public}s", text.c_str());
|
||||
SHERPA_ONNX_LOGE("after replacing punctuations: %{public}s", s.c_str());
|
||||
|
||||
SHERPA_ONNX_LOGE("after jieba processing: %{public}s",
|
||||
os.str().c_str());
|
||||
#else
|
||||
SHERPA_ONNX_LOGE("input text: %s", text.c_str());
|
||||
SHERPA_ONNX_LOGE("after replacing punctuations: %s", s.c_str());
|
||||
|
||||
SHERPA_ONNX_LOGE("after jieba processing: %s", os.str().c_str());
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
words = SplitUtf8(text);
|
||||
@@ -102,7 +173,7 @@ class MeloTtsLexicon::Impl {
|
||||
if (debug_) {
|
||||
fprintf(stderr, "Input text in string (lowercase): %s\n", text.c_str());
|
||||
fprintf(stderr, "Input text in bytes (lowercase):");
|
||||
for (uint8_t c : text) {
|
||||
for (int8_t c : text) {
|
||||
fprintf(stderr, " %02x", c);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
@@ -307,9 +378,48 @@ MeloTtsLexicon::MeloTtsLexicon(const std::string &lexicon,
|
||||
bool debug)
|
||||
: impl_(std::make_unique<Impl>(lexicon, tokens, meta_data, debug)) {}
|
||||
|
||||
template <typename Manager>
|
||||
MeloTtsLexicon::MeloTtsLexicon(Manager *mgr, const std::string &lexicon,
|
||||
const std::string &tokens,
|
||||
const std::string &dict_dir,
|
||||
const OfflineTtsVitsModelMetaData &meta_data,
|
||||
bool debug)
|
||||
: impl_(std::make_unique<Impl>(mgr, lexicon, tokens, dict_dir, meta_data,
|
||||
debug)) {}
|
||||
|
||||
template <typename Manager>
|
||||
MeloTtsLexicon::MeloTtsLexicon(Manager *mgr, const std::string &lexicon,
|
||||
const std::string &tokens,
|
||||
const OfflineTtsVitsModelMetaData &meta_data,
|
||||
bool debug)
|
||||
: impl_(std::make_unique<Impl>(mgr, lexicon, tokens, meta_data, debug)) {}
|
||||
|
||||
std::vector<TokenIDs> MeloTtsLexicon::ConvertTextToTokenIds(
|
||||
const std::string &text, const std::string & /*unused_voice = ""*/) const {
|
||||
return impl_->ConvertTextToTokenIds(text);
|
||||
}
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
template MeloTtsLexicon::MeloTtsLexicon(
|
||||
AAssetManager *mgr, const std::string &lexicon, const std::string &tokens,
|
||||
const std::string &dict_dir, const OfflineTtsVitsModelMetaData &meta_data,
|
||||
bool debug);
|
||||
|
||||
template MeloTtsLexicon::MeloTtsLexicon(
|
||||
AAssetManager *mgr, const std::string &lexicon, const std::string &tokens,
|
||||
const OfflineTtsVitsModelMetaData &meta_data, bool debug);
|
||||
#endif
|
||||
|
||||
#if __OHOS__
|
||||
template MeloTtsLexicon::MeloTtsLexicon(
|
||||
NativeResourceManager *mgr, const std::string &lexicon,
|
||||
const std::string &tokens, const std::string &dict_dir,
|
||||
const OfflineTtsVitsModelMetaData &meta_data, bool debug);
|
||||
|
||||
template MeloTtsLexicon::MeloTtsLexicon(
|
||||
NativeResourceManager *mgr, const std::string &lexicon,
|
||||
const std::string &tokens, const OfflineTtsVitsModelMetaData &meta_data,
|
||||
bool debug);
|
||||
#endif
|
||||
|
||||
} // namespace sherpa_onnx
|
||||
|
||||
Reference in New Issue
Block a user