Fangjun Kuang
Committed by GitHub

Add HarmonyOS support for text-to-speech. (#1584)

正在显示 33 个修改的文件 包含 327 行增加127 行删除
@@ -56,7 +56,7 @@ jobs: @@ -56,7 +56,7 @@ jobs:
56 key: ${{ matrix.os }} 56 key: ${{ matrix.os }}
57 57
58 # See https://github.com/gcarreno/setup-lazarus 58 # See https://github.com/gcarreno/setup-lazarus
59 - - uses: gcarreno/setup-lazarus@v3 59 + - uses: gcarreno/setup-lazarus@v3.3.1
60 with: 60 with:
61 lazarus-version: "stable" 61 lazarus-version: "stable"
62 with-cache: true 62 with-cache: true
@@ -26,7 +26,7 @@ jobs: @@ -26,7 +26,7 @@ jobs:
26 fail-fast: false 26 fail-fast: false
27 matrix: 27 matrix:
28 os: [ubuntu-latest, macos-latest, windows-2019] 28 os: [ubuntu-latest, macos-latest, windows-2019]
29 - python-version: ["3.8"] 29 + python-version: ["3.10"]
30 30
31 steps: 31 steps:
32 - uses: actions/checkout@v4 32 - uses: actions/checkout@v4
@@ -2,8 +2,8 @@ @@ -2,8 +2,8 @@
2 * Use these variables when you tailor your ArkTS code. They must be of the const type. 2 * Use these variables when you tailor your ArkTS code. They must be of the const type.
3 */ 3 */
4 export const HAR_VERSION = '1.10.32'; 4 export const HAR_VERSION = '1.10.32';
5 -export const BUILD_MODE_NAME = 'release';  
6 -export const DEBUG = false; 5 +export const BUILD_MODE_NAME = 'debug';
  6 +export const DEBUG = true;
7 export const TARGET_NAME = 'default'; 7 export const TARGET_NAME = 'default';
8 8
9 /** 9 /**
@@ -38,3 +38,12 @@ export { @@ -38,3 +38,12 @@ export {
38 OnlineRecognizerResult, 38 OnlineRecognizerResult,
39 OnlineRecognizer, 39 OnlineRecognizer,
40 } from './src/main/ets/components/StreamingAsr'; 40 } from './src/main/ets/components/StreamingAsr';
  41 +
  42 +export {
  43 + OfflineTtsVitsModelConfig,
  44 + OfflineTtsModelConfig,
  45 + OfflineTtsConfig,
  46 + OfflineTts,
  47 + TtsOutput,
  48 + TtsInput,
  49 +} from './src/main/ets/components/NonStreamingTts';
@@ -8,8 +8,8 @@ @@ -8,8 +8,8 @@
8 #include <string> 8 #include <string>
9 9
10 #if __OHOS__ 10 #if __OHOS__
11 -#include "rawfile/raw_file_manager.h"  
12 #include "hilog/log.h" 11 #include "hilog/log.h"
  12 +#include "rawfile/raw_file_manager.h"
13 13
14 #undef LOG_DOMAIN 14 #undef LOG_DOMAIN
15 #undef LOG_TAG 15 #undef LOG_TAG
@@ -236,7 +236,10 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { @@ -236,7 +236,10 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) {
236 SHERPA_ONNX_ASSIGN_ATTR_FLOAT(blank_penalty, blankPenalty); 236 SHERPA_ONNX_ASSIGN_ATTR_FLOAT(blank_penalty, blankPenalty);
237 237
238 #if __OHOS__ 238 #if __OHOS__
239 - std::unique_ptr<NativeResourceManager, decltype(&OH_ResourceManager_ReleaseNativeResourceManager)> mgr (OH_ResourceManager_InitNativeResourceManager(env, info[1]), &OH_ResourceManager_ReleaseNativeResourceManager); 239 + std::unique_ptr<NativeResourceManager,
  240 + decltype(&OH_ResourceManager_ReleaseNativeResourceManager)>
  241 + mgr(OH_ResourceManager_InitNativeResourceManager(env, info[1]),
  242 + &OH_ResourceManager_ReleaseNativeResourceManager);
240 243
241 const SherpaOnnxOfflineRecognizer *recognizer = 244 const SherpaOnnxOfflineRecognizer *recognizer =
242 SherpaOnnxCreateOfflineRecognizerOHOS(&c, mgr.get()); 245 SherpaOnnxCreateOfflineRecognizerOHOS(&c, mgr.get());
@@ -63,6 +63,17 @@ static SherpaOnnxOfflineTtsModelConfig GetOfflineTtsModelConfig( @@ -63,6 +63,17 @@ static SherpaOnnxOfflineTtsModelConfig GetOfflineTtsModelConfig(
63 static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper( 63 static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper(
64 const Napi::CallbackInfo &info) { 64 const Napi::CallbackInfo &info) {
65 Napi::Env env = info.Env(); 65 Napi::Env env = info.Env();
  66 +#if __OHOS__
  67 + // the last argument is the NativeResourceManager
  68 + if (info.Length() != 2) {
  69 + std::ostringstream os;
  70 + os << "Expect only 2 arguments. Given: " << info.Length();
  71 +
  72 + Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException();
  73 +
  74 + return {};
  75 + }
  76 +#else
66 if (info.Length() != 1) { 77 if (info.Length() != 1) {
67 std::ostringstream os; 78 std::ostringstream os;
68 os << "Expect only 1 argument. Given: " << info.Length(); 79 os << "Expect only 1 argument. Given: " << info.Length();
@@ -71,6 +82,7 @@ static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper( @@ -71,6 +82,7 @@ static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper(
71 82
72 return {}; 83 return {};
73 } 84 }
  85 +#endif
74 86
75 if (!info[0].IsObject()) { 87 if (!info[0].IsObject()) {
76 Napi::TypeError::New(env, "Expect an object as the argument") 88 Napi::TypeError::New(env, "Expect an object as the argument")
@@ -90,7 +102,15 @@ static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper( @@ -90,7 +102,15 @@ static Napi::External<SherpaOnnxOfflineTts> CreateOfflineTtsWrapper(
90 SHERPA_ONNX_ASSIGN_ATTR_INT32(max_num_sentences, maxNumSentences); 102 SHERPA_ONNX_ASSIGN_ATTR_INT32(max_num_sentences, maxNumSentences);
91 SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars); 103 SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars);
92 104
  105 +#if __OHOS__
  106 + std::unique_ptr<NativeResourceManager,
  107 + decltype(&OH_ResourceManager_ReleaseNativeResourceManager)>
  108 + mgr(OH_ResourceManager_InitNativeResourceManager(env, info[1]),
  109 + &OH_ResourceManager_ReleaseNativeResourceManager);
  110 + SherpaOnnxOfflineTts *tts = SherpaOnnxCreateOfflineTtsOHOS(&c, mgr.get());
  111 +#else
93 SherpaOnnxOfflineTts *tts = SherpaOnnxCreateOfflineTts(&c); 112 SherpaOnnxOfflineTts *tts = SherpaOnnxCreateOfflineTts(&c);
  113 +#endif
94 114
95 if (c.model.vits.model) { 115 if (c.model.vits.model) {
96 delete[] c.model.vits.model; 116 delete[] c.model.vits.model;
@@ -211,7 +211,10 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( @@ -211,7 +211,10 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
211 c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o); 211 c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o);
212 212
213 #if __OHOS__ 213 #if __OHOS__
214 - std::unique_ptr<NativeResourceManager, decltype(&OH_ResourceManager_ReleaseNativeResourceManager)> mgr (OH_ResourceManager_InitNativeResourceManager(env, info[1]), &OH_ResourceManager_ReleaseNativeResourceManager); 214 + std::unique_ptr<NativeResourceManager,
  215 + decltype(&OH_ResourceManager_ReleaseNativeResourceManager)>
  216 + mgr(OH_ResourceManager_InitNativeResourceManager(env, info[1]),
  217 + &OH_ResourceManager_ReleaseNativeResourceManager);
215 218
216 const SherpaOnnxOnlineRecognizer *recognizer = 219 const SherpaOnnxOnlineRecognizer *recognizer =
217 SherpaOnnxCreateOnlineRecognizerOHOS(&c, mgr.get()); 220 SherpaOnnxCreateOnlineRecognizerOHOS(&c, mgr.get());
@@ -33,3 +33,8 @@ export const decodeOnlineStream: (handle: object, streamHandle: object) => void; @@ -33,3 +33,8 @@ export const decodeOnlineStream: (handle: object, streamHandle: object) => void;
33 export const isEndpoint: (handle: object, streamHandle: object) => boolean; 33 export const isEndpoint: (handle: object, streamHandle: object) => boolean;
34 export const reset: (handle: object, streamHandle: object) => void; 34 export const reset: (handle: object, streamHandle: object) => void;
35 export const getOnlineStreamResultAsJson: (handle: object, streamHandle: object) => string; 35 export const getOnlineStreamResultAsJson: (handle: object, streamHandle: object) => string;
  36 +
  37 +export const createOfflineTts: (config: object, mgr?: object) => object;
  38 +export const getOfflineTtsNumSpeakers: (handle: object) => number;
  39 +export const getOfflineTtsSampleRate: (handle: object) => number;
  40 +export const offlineTtsGenerate: (handle: object, input: object) => object;
@@ -70,8 +70,10 @@ static void CircularBufferPushWrapper(const Napi::CallbackInfo &info) { @@ -70,8 +70,10 @@ static void CircularBufferPushWrapper(const Napi::CallbackInfo &info) {
70 70
71 #if __OHOS__ 71 #if __OHOS__
72 // Note(fangjun): Normally, we don't need to divied it by sizeof(float). 72 // Note(fangjun): Normally, we don't need to divied it by sizeof(float).
73 - // However, data.ElementLength() here returns number of bytes, not number of elements.  
74 - SherpaOnnxCircularBufferPush(buf, data.Data(), data.ElementLength() / sizeof(float)); 73 + // However, data.ElementLength() here returns number of bytes, not number of
  74 + // elements.
  75 + SherpaOnnxCircularBufferPush(buf, data.Data(),
  76 + data.ElementLength() / sizeof(float));
75 #else 77 #else
76 SherpaOnnxCircularBufferPush(buf, data.Data(), data.ElementLength()); 78 SherpaOnnxCircularBufferPush(buf, data.Data(), data.ElementLength());
77 #endif 79 #endif
@@ -353,10 +355,14 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { @@ -353,10 +355,14 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) {
353 float buffer_size_in_seconds = info[1].As<Napi::Number>().FloatValue(); 355 float buffer_size_in_seconds = info[1].As<Napi::Number>().FloatValue();
354 356
355 #if __OHOS__ 357 #if __OHOS__
356 - std::unique_ptr<NativeResourceManager, decltype(&OH_ResourceManager_ReleaseNativeResourceManager)> mgr(OH_ResourceManager_InitNativeResourceManager(env, info[2]), &OH_ResourceManager_ReleaseNativeResourceManager); 358 + std::unique_ptr<NativeResourceManager,
  359 + decltype(&OH_ResourceManager_ReleaseNativeResourceManager)>
  360 + mgr(OH_ResourceManager_InitNativeResourceManager(env, info[2]),
  361 + &OH_ResourceManager_ReleaseNativeResourceManager);
357 362
358 SherpaOnnxVoiceActivityDetector *vad = 363 SherpaOnnxVoiceActivityDetector *vad =
359 - SherpaOnnxCreateVoiceActivityDetectorOHOS(&c, buffer_size_in_seconds, mgr.get()); 364 + SherpaOnnxCreateVoiceActivityDetectorOHOS(&c, buffer_size_in_seconds,
  365 + mgr.get());
360 #else 366 #else
361 SherpaOnnxVoiceActivityDetector *vad = 367 SherpaOnnxVoiceActivityDetector *vad =
362 SherpaOnnxCreateVoiceActivityDetector(&c, buffer_size_in_seconds); 368 SherpaOnnxCreateVoiceActivityDetector(&c, buffer_size_in_seconds);
@@ -410,9 +416,10 @@ static void VoiceActivityDetectorAcceptWaveformWrapper( @@ -410,9 +416,10 @@ static void VoiceActivityDetectorAcceptWaveformWrapper(
410 Napi::Float32Array samples = info[1].As<Napi::Float32Array>(); 416 Napi::Float32Array samples = info[1].As<Napi::Float32Array>();
411 417
412 #if __OHOS__ 418 #if __OHOS__
413 - // Note(fangjun): For unknown reasons, we need to use `/sizeof(float)` here for Huawei  
414 - SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples.Data(),  
415 - samples.ElementLength() / sizeof(float)); 419 + // Note(fangjun): For unknown reasons, we need to use `/sizeof(float)` here
  420 + // for Huawei
  421 + SherpaOnnxVoiceActivityDetectorAcceptWaveform(
  422 + vad, samples.Data(), samples.ElementLength() / sizeof(float));
416 #else 423 #else
417 SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples.Data(), 424 SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples.Data(),
418 samples.ElementLength()); 425 samples.ElementLength());
@@ -105,7 +105,8 @@ static Napi::Object ReadWaveFromBinaryWrapper(const Napi::CallbackInfo &info) { @@ -105,7 +105,8 @@ static Napi::Object ReadWaveFromBinaryWrapper(const Napi::CallbackInfo &info) {
105 105
106 Napi::Uint8Array data = info[0].As<Napi::Uint8Array>(); 106 Napi::Uint8Array data = info[0].As<Napi::Uint8Array>();
107 int32_t n = data.ElementLength(); 107 int32_t n = data.ElementLength();
108 - const SherpaOnnxWave *wave = SherpaOnnxReadWaveFromBinaryData(reinterpret_cast<const char*>(data.Data()), n); 108 + const SherpaOnnxWave *wave = SherpaOnnxReadWaveFromBinaryData(
  109 + reinterpret_cast<const char *>(data.Data()), n);
109 if (!wave) { 110 if (!wave) {
110 std::ostringstream os; 111 std::ostringstream os;
111 os << "Failed to read wave"; 112 os << "Failed to read wave";
@@ -79,7 +79,7 @@ export class OfflineModelConfig { @@ -79,7 +79,7 @@ export class OfflineModelConfig {
79 public tokens: string = ''; 79 public tokens: string = '';
80 public numThreads: number = 1; 80 public numThreads: number = 1;
81 public debug: boolean = false; 81 public debug: boolean = false;
82 - public provider: string = "cpu"; 82 + public provider: string = 'cpu';
83 public modelType: string = ''; 83 public modelType: string = '';
84 public modelingUnit: string = "cjkchar"; 84 public modelingUnit: string = "cjkchar";
85 public bpeVocab: string = ''; 85 public bpeVocab: string = '';
  1 +import {
  2 + createOfflineTts,
  3 + getOfflineTtsNumSpeakers,
  4 + getOfflineTtsSampleRate,
  5 + offlineTtsGenerate,
  6 +} from "libsherpa_onnx.so";
  7 +
  8 +export class OfflineTtsVitsModelConfig {
  9 + public model: string = '';
  10 + public lexicon: string = '';
  11 + public tokens: string = '';
  12 + public dataDir: string = '';
  13 + public dictDir: String = '';
  14 + public noiseScale: number = 0.667;
  15 + public noiseScaleW: number = 0.8;
  16 + public lengthScale: number = 1.0;
  17 +}
  18 +
  19 +export class OfflineTtsModelConfig{
  20 + public vits: OfflineTtsVitsModelConfig = new OfflineTtsVitsModelConfig();
  21 + public numThreads: number = 1;
  22 + public debug: boolean = false;
  23 + public provider: string = 'cpu';
  24 +}
  25 +
  26 +export class OfflineTtsConfig{
  27 + public model: OfflineTtsModelConfig = new OfflineTtsModelConfig();
  28 + public ruleFsts: string = '';
  29 + public ruleFars: string = '';
  30 + public maxNumSentences: number = 1;
  31 +}
  32 +
  33 +export class TtsOutput {
  34 + public samples: Float32Array = new Float32Array(0);
  35 + public sampleRate: number = 0;
  36 +}
  37 +
  38 +export class TtsInput {
  39 + public text: string = '';
  40 + public sid: number = 0;
  41 + public speed: number = 1.0;
  42 +}
  43 +
  44 +export class OfflineTts {
  45 + private handle: object;
  46 + public config: OfflineTtsConfig;
  47 + public numSpeakers: number;
  48 + public sampleRate: number;
  49 + constructor(config: OfflineTtsConfig, mgr?: object) {
  50 + this.handle = createOfflineTts(config, mgr);
  51 + this.config = config;
  52 +
  53 + this.numSpeakers = getOfflineTtsNumSpeakers(this.handle);
  54 + this.sampleRate = getOfflineTtsSampleRate(this.handle);
  55 + }
  56 +
  57 + /*
  58 + input obj: {text: "xxxx", sid: 0, speed: 1.0}
  59 + where text is a string, sid is a int32, speed is a float
  60 +
  61 + return an object {samples: Float32Array, sampleRate: <a number>}
  62 + */
  63 + generate(input: TtsInput): TtsOutput {
  64 + return offlineTtsGenerate(this.handle, input) as TtsOutput;
  65 + }
  66 +}
@@ -52,7 +52,7 @@ export class OnlineModelConfig { @@ -52,7 +52,7 @@ export class OnlineModelConfig {
52 public zipformer2_ctc: OnlineZipformer2CtcModelConfig = new OnlineZipformer2CtcModelConfig(); 52 public zipformer2_ctc: OnlineZipformer2CtcModelConfig = new OnlineZipformer2CtcModelConfig();
53 public tokens: string = ''; 53 public tokens: string = '';
54 public numThreads: number = 1; 54 public numThreads: number = 1;
55 - public provider: string = "cpu"; 55 + public provider: string = 'cpu';
56 public debug: boolean = false; 56 public debug: boolean = false;
57 public modelType: string = ''; 57 public modelType: string = '';
58 public modelingUnit: string = "cjkchar"; 58 public modelingUnit: string = "cjkchar";
@@ -67,7 +67,7 @@ export class OnlineCtcFstDecoderConfig { @@ -67,7 +67,7 @@ export class OnlineCtcFstDecoderConfig {
67 export class OnlineRecognizerConfig { 67 export class OnlineRecognizerConfig {
68 public featConfig: FeatureConfig = new FeatureConfig(); 68 public featConfig: FeatureConfig = new FeatureConfig();
69 public modelConfig: OnlineModelConfig = new OnlineModelConfig(); 69 public modelConfig: OnlineModelConfig = new OnlineModelConfig();
70 - public decodingMethod: string = "greedy_search"; 70 + public decodingMethod: string = 'greedy_search';
71 public maxActivePaths: number = 4; 71 public maxActivePaths: number = 4;
72 public enableEndpoint: boolean = false; 72 public enableEndpoint: boolean = false;
73 public rule1MinTrailingSilence: number = 2.4; 73 public rule1MinTrailingSilence: number = 2.4;
@@ -54,9 +54,9 @@ @@ -54,9 +54,9 @@
54 "reason": "$string:mic_reason", 54 "reason": "$string:mic_reason",
55 "usedScene": { 55 "usedScene": {
56 "abilities": [ 56 "abilities": [
57 - "FormAbility", 57 + "EntryAbility",
58 ], 58 ],
59 - "when": "always", 59 + "when": "inuse",
60 } 60 }
61 } 61 }
62 ] 62 ]
@@ -103,6 +103,7 @@ function do_check() { @@ -103,6 +103,7 @@ function do_check() {
103 2) 103 2)
104 echo "Check all files" 104 echo "Check all files"
105 files=$(find $sherpa_onnx_dir/cxx-api-examples $sherpa_onnx_dir/c-api-examples $sherpa_onnx_dir/sherpa-onnx/csrc $sherpa_onnx_dir/sherpa-onnx/python $sherpa_onnx_dir/scripts/node-addon-api/src $sherpa_onnx_dir/sherpa-onnx/jni $sherpa_onnx_dir/sherpa-onnx/c-api -name "*.h" -o -name "*.cc") 105 files=$(find $sherpa_onnx_dir/cxx-api-examples $sherpa_onnx_dir/c-api-examples $sherpa_onnx_dir/sherpa-onnx/csrc $sherpa_onnx_dir/sherpa-onnx/python $sherpa_onnx_dir/scripts/node-addon-api/src $sherpa_onnx_dir/sherpa-onnx/jni $sherpa_onnx_dir/sherpa-onnx/c-api -name "*.h" -o -name "*.cc")
  106 + files2=$(find $sherpa_onnx_dir/harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/ -name "*.cc")
106 ;; 107 ;;
107 *) 108 *)
108 echo "Check last commit" 109 echo "Check last commit"
@@ -110,7 +111,7 @@ function do_check() { @@ -110,7 +111,7 @@ function do_check() {
110 ;; 111 ;;
111 esac 112 esac
112 113
113 - for f in $files; do 114 + for f in $files $files2; do
114 need_check=$(is_source_code_file $f) 115 need_check=$(is_source_code_file $f)
115 if $need_check; then 116 if $need_check; then
116 [[ -f $f ]] && check_style $f 117 [[ -f $f ]] && check_style $f
@@ -485,9 +485,9 @@ static sherpa_onnx::OfflineRecognizerConfig GetOfflineRecognizerConfig( @@ -485,9 +485,9 @@ static sherpa_onnx::OfflineRecognizerConfig GetOfflineRecognizerConfig(
485 485
486 if (config->model_config.debug) { 486 if (config->model_config.debug) {
487 #if __OHOS__ 487 #if __OHOS__
488 - SHERPA_ONNX_LOGE("%{public}s", recognizer_config.ToString().c_str()); 488 + SHERPA_ONNX_LOGE("%{public}s\n", recognizer_config.ToString().c_str());
489 #else 489 #else
490 - SHERPA_ONNX_LOGE("%s", recognizer_config.ToString().c_str()); 490 + SHERPA_ONNX_LOGE("%s\n", recognizer_config.ToString().c_str());
491 #endif 491 #endif
492 } 492 }
493 493
@@ -967,9 +967,9 @@ sherpa_onnx::VadModelConfig GetVadModelConfig( @@ -967,9 +967,9 @@ sherpa_onnx::VadModelConfig GetVadModelConfig(
967 967
968 if (vad_config.debug) { 968 if (vad_config.debug) {
969 #if __OHOS__ 969 #if __OHOS__
970 - SHERPA_ONNX_LOGE("%{public}s", vad_config.ToString().c_str()); 970 + SHERPA_ONNX_LOGE("%{public}s\n", vad_config.ToString().c_str());
971 #else 971 #else
972 - SHERPA_ONNX_LOGE("%s", vad_config.ToString().c_str()); 972 + SHERPA_ONNX_LOGE("%s\n", vad_config.ToString().c_str());
973 #endif 973 #endif
974 } 974 }
975 975
@@ -1053,7 +1053,7 @@ struct SherpaOnnxOfflineTts { @@ -1053,7 +1053,7 @@ struct SherpaOnnxOfflineTts {
1053 std::unique_ptr<sherpa_onnx::OfflineTts> impl; 1053 std::unique_ptr<sherpa_onnx::OfflineTts> impl;
1054 }; 1054 };
1055 1055
1056 -SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTts( 1056 +static sherpa_onnx::OfflineTtsConfig GetOfflineTtsConfig(
1057 const SherpaOnnxOfflineTtsConfig *config) { 1057 const SherpaOnnxOfflineTtsConfig *config) {
1058 sherpa_onnx::OfflineTtsConfig tts_config; 1058 sherpa_onnx::OfflineTtsConfig tts_config;
1059 1059
@@ -1084,9 +1084,20 @@ SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTts( @@ -1084,9 +1084,20 @@ SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTts(
1084 tts_config.max_num_sentences = SHERPA_ONNX_OR(config->max_num_sentences, 2); 1084 tts_config.max_num_sentences = SHERPA_ONNX_OR(config->max_num_sentences, 2);
1085 1085
1086 if (tts_config.model.debug) { 1086 if (tts_config.model.debug) {
  1087 +#if __OHOS__
  1088 + SHERPA_ONNX_LOGE("%{public}s\n", tts_config.ToString().c_str());
  1089 +#else
1087 SHERPA_ONNX_LOGE("%s\n", tts_config.ToString().c_str()); 1090 SHERPA_ONNX_LOGE("%s\n", tts_config.ToString().c_str());
  1091 +#endif
1088 } 1092 }
1089 1093
  1094 + return tts_config;
  1095 +}
  1096 +
  1097 +SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTts(
  1098 + const SherpaOnnxOfflineTtsConfig *config) {
  1099 + auto tts_config = GetOfflineTtsConfig(config);
  1100 +
1090 if (!tts_config.Validate()) { 1101 if (!tts_config.Validate()) {
1091 SHERPA_ONNX_LOGE("Errors in config"); 1102 SHERPA_ONNX_LOGE("Errors in config");
1092 return nullptr; 1103 return nullptr;
@@ -1908,6 +1919,7 @@ SherpaOnnxOfflineSpeakerDiarizationProcessWithCallbackNoArg( @@ -1908,6 +1919,7 @@ SherpaOnnxOfflineSpeakerDiarizationProcessWithCallbackNoArg(
1908 1919
1909 return ans; 1920 return ans;
1910 } 1921 }
  1922 +#endif
1911 1923
1912 #ifdef __OHOS__ 1924 #ifdef __OHOS__
1913 1925
@@ -1959,6 +1971,23 @@ SherpaOnnxVoiceActivityDetector *SherpaOnnxCreateVoiceActivityDetectorOHOS( @@ -1959,6 +1971,23 @@ SherpaOnnxVoiceActivityDetector *SherpaOnnxCreateVoiceActivityDetectorOHOS(
1959 1971
1960 return p; 1972 return p;
1961 } 1973 }
1962 -#endif  
1963 1974
1964 -#endif 1975 +#if SHERPA_ONNX_ENABLE_TTS == 1
  1976 +SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTtsOHOS(
  1977 + const SherpaOnnxOfflineTtsConfig *config, NativeResourceManager *mgr) {
  1978 + if (!mgr) {
  1979 + return SherpaOnnxCreateOfflineTts(config);
  1980 + }
  1981 +
  1982 + auto tts_config = GetOfflineTtsConfig(config);
  1983 +
  1984 + SherpaOnnxOfflineTts *tts = new SherpaOnnxOfflineTts;
  1985 +
  1986 + tts->impl = std::make_unique<sherpa_onnx::OfflineTts>(mgr, tts_config);
  1987 +
  1988 + return tts;
  1989 +}
  1990 +
  1991 +#endif // #if SHERPA_ONNX_ENABLE_TTS == 1
  1992 +
  1993 +#endif // #ifdef __OHOS__
@@ -1558,6 +1558,9 @@ SHERPA_ONNX_API SherpaOnnxVoiceActivityDetector * @@ -1558,6 +1558,9 @@ SHERPA_ONNX_API SherpaOnnxVoiceActivityDetector *
1558 SherpaOnnxCreateVoiceActivityDetectorOHOS( 1558 SherpaOnnxCreateVoiceActivityDetectorOHOS(
1559 const SherpaOnnxVadModelConfig *config, float buffer_size_in_seconds, 1559 const SherpaOnnxVadModelConfig *config, float buffer_size_in_seconds,
1560 NativeResourceManager *mgr); 1560 NativeResourceManager *mgr);
  1561 +
  1562 +SHERPA_ONNX_API SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTtsOHOS(
  1563 + const SherpaOnnxOfflineTtsConfig *config, NativeResourceManager *mgr);
1561 #endif 1564 #endif
1562 1565
1563 #if defined(__GNUC__) 1566 #if defined(__GNUC__)
@@ -7,17 +7,19 @@ @@ -7,17 +7,19 @@
7 #include <algorithm> 7 #include <algorithm>
8 #include <cctype> 8 #include <cctype>
9 #include <fstream> 9 #include <fstream>
  10 +#include <memory>
10 #include <sstream> 11 #include <sstream>
  12 +#include <strstream>
11 #include <utility> 13 #include <utility>
12 14
13 #if __ANDROID_API__ >= 9 15 #if __ANDROID_API__ >= 9
14 -#include <strstream>  
15 -  
16 #include "android/asset_manager.h" 16 #include "android/asset_manager.h"
17 #include "android/asset_manager_jni.h" 17 #include "android/asset_manager_jni.h"
18 #endif 18 #endif
19 19
20 -#include <memory> 20 +#if __OHOS__
  21 +#include "rawfile/raw_file_manager.h"
  22 +#endif
21 23
22 #include "sherpa-onnx/csrc/macros.h" 24 #include "sherpa-onnx/csrc/macros.h"
23 #include "sherpa-onnx/csrc/onnx-utils.h" 25 #include "sherpa-onnx/csrc/onnx-utils.h"
@@ -110,8 +112,8 @@ Lexicon::Lexicon(const std::string &lexicon, const std::string &tokens, @@ -110,8 +112,8 @@ Lexicon::Lexicon(const std::string &lexicon, const std::string &tokens,
110 InitPunctuations(punctuations); 112 InitPunctuations(punctuations);
111 } 113 }
112 114
113 -#if __ANDROID_API__ >= 9  
114 -Lexicon::Lexicon(AAssetManager *mgr, const std::string &lexicon, 115 +template <typename Manager>
  116 +Lexicon::Lexicon(Manager *mgr, const std::string &lexicon,
115 const std::string &tokens, const std::string &punctuations, 117 const std::string &tokens, const std::string &punctuations,
116 const std::string &language, bool debug /*= false*/ 118 const std::string &language, bool debug /*= false*/
117 ) 119 )
@@ -132,7 +134,6 @@ Lexicon::Lexicon(AAssetManager *mgr, const std::string &lexicon, @@ -132,7 +134,6 @@ Lexicon::Lexicon(AAssetManager *mgr, const std::string &lexicon,
132 134
133 InitPunctuations(punctuations); 135 InitPunctuations(punctuations);
134 } 136 }
135 -#endif  
136 137
137 std::vector<TokenIDs> Lexicon::ConvertTextToTokenIds( 138 std::vector<TokenIDs> Lexicon::ConvertTextToTokenIds(
138 const std::string &text, const std::string & /*voice*/ /*= ""*/) const { 139 const std::string &text, const std::string & /*voice*/ /*= ""*/) const {
@@ -371,4 +372,18 @@ void Lexicon::InitPunctuations(const std::string &punctuations) { @@ -371,4 +372,18 @@ void Lexicon::InitPunctuations(const std::string &punctuations) {
371 } 372 }
372 } 373 }
373 374
  375 +#if __ANDROID_API__ >= 9
  376 +template Lexicon::Lexicon(AAssetManager *mgr, const std::string &lexicon,
  377 + const std::string &tokens,
  378 + const std::string &punctuations,
  379 + const std::string &language, bool debug = false);
  380 +#endif
  381 +
  382 +#if __OHOS__
  383 +template Lexicon::Lexicon(NativeResourceManager *mgr,
  384 + const std::string &lexicon, const std::string &tokens,
  385 + const std::string &punctuations,
  386 + const std::string &language, bool debug = false);
  387 +#endif
  388 +
374 } // namespace sherpa_onnx 389 } // namespace sherpa_onnx
@@ -13,11 +13,6 @@ @@ -13,11 +13,6 @@
13 #include <unordered_set> 13 #include <unordered_set>
14 #include <vector> 14 #include <vector>
15 15
16 -#if __ANDROID_API__ >= 9  
17 -#include "android/asset_manager.h"  
18 -#include "android/asset_manager_jni.h"  
19 -#endif  
20 -  
21 #include "sherpa-onnx/csrc/offline-tts-frontend.h" 16 #include "sherpa-onnx/csrc/offline-tts-frontend.h"
22 17
23 namespace sherpa_onnx { 18 namespace sherpa_onnx {
@@ -31,11 +26,10 @@ class Lexicon : public OfflineTtsFrontend { @@ -31,11 +26,10 @@ class Lexicon : public OfflineTtsFrontend {
31 const std::string &punctuations, const std::string &language, 26 const std::string &punctuations, const std::string &language,
32 bool debug = false); 27 bool debug = false);
33 28
34 -#if __ANDROID_API__ >= 9  
35 - Lexicon(AAssetManager *mgr, const std::string &lexicon,  
36 - const std::string &tokens, const std::string &punctuations,  
37 - const std::string &language, bool debug = false);  
38 -#endif 29 + template <typename Manager>
  30 + Lexicon(Manager *mgr, const std::string &lexicon, const std::string &tokens,
  31 + const std::string &punctuations, const std::string &language,
  32 + bool debug = false);
39 33
40 std::vector<TokenIDs> ConvertTextToTokenIds( 34 std::vector<TokenIDs> ConvertTextToTokenIds(
41 const std::string &text, const std::string &voice = "") const override; 35 const std::string &text, const std::string &voice = "") const override;
@@ -136,7 +136,6 @@ std::unique_ptr<OfflineCtcModel> OfflineCtcModel::Create( @@ -136,7 +136,6 @@ std::unique_ptr<OfflineCtcModel> OfflineCtcModel::Create(
136 136
137 switch (model_type) { 137 switch (model_type) {
138 case ModelType::kEncDecCTCModelBPE: 138 case ModelType::kEncDecCTCModelBPE:
139 - return std::make_unique<OfflineNemoEncDecCtcModel>(config);  
140 case ModelType::kEncDecCTCModel: 139 case ModelType::kEncDecCTCModel:
141 return std::make_unique<OfflineNemoEncDecCtcModel>(config); 140 return std::make_unique<OfflineNemoEncDecCtcModel>(config);
142 case ModelType::kEncDecHybridRNNTCTCBPEModel: 141 case ModelType::kEncDecHybridRNNTCTCBPEModel:
@@ -187,7 +186,6 @@ std::unique_ptr<OfflineCtcModel> OfflineCtcModel::Create( @@ -187,7 +186,6 @@ std::unique_ptr<OfflineCtcModel> OfflineCtcModel::Create(
187 186
188 switch (model_type) { 187 switch (model_type) {
189 case ModelType::kEncDecCTCModelBPE: 188 case ModelType::kEncDecCTCModelBPE:
190 - return std::make_unique<OfflineNemoEncDecCtcModel>(mgr, config);  
191 case ModelType::kEncDecCTCModel: 189 case ModelType::kEncDecCTCModel:
192 return std::make_unique<OfflineNemoEncDecCtcModel>(mgr, config); 190 return std::make_unique<OfflineNemoEncDecCtcModel>(mgr, config);
193 case ModelType::kEncDecHybridRNNTCTCBPEModel: 191 case ModelType::kEncDecHybridRNNTCTCBPEModel:
@@ -2,20 +2,24 @@ @@ -2,20 +2,24 @@
2 // 2 //
3 // Copyright (c) 2023 Xiaomi Corporation 3 // Copyright (c) 2023 Xiaomi Corporation
4 4
5 -#if __ANDROID_API__ >= 9  
6 -#include <strstream>  
7 -  
8 -#include "android/asset_manager.h"  
9 -#include "android/asset_manager_jni.h"  
10 -#endif  
11 #include <algorithm> 5 #include <algorithm>
12 #include <cctype> 6 #include <cctype>
13 #include <codecvt> 7 #include <codecvt>
14 #include <fstream> 8 #include <fstream>
15 #include <locale> 9 #include <locale>
16 #include <sstream> 10 #include <sstream>
  11 +#include <strstream>
17 #include <utility> 12 #include <utility>
18 13
  14 +#if __ANDROID_API__ >= 9
  15 +#include "android/asset_manager.h"
  16 +#include "android/asset_manager_jni.h"
  17 +#endif
  18 +
  19 +#if __OHOS__
  20 +#include "rawfile/raw_file_manager.h"
  21 +#endif
  22 +
19 #include "sherpa-onnx/csrc/macros.h" 23 #include "sherpa-onnx/csrc/macros.h"
20 #include "sherpa-onnx/csrc/offline-tts-character-frontend.h" 24 #include "sherpa-onnx/csrc/offline-tts-character-frontend.h"
21 #include "sherpa-onnx/csrc/onnx-utils.h" 25 #include "sherpa-onnx/csrc/onnx-utils.h"
@@ -82,9 +86,9 @@ OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend( @@ -82,9 +86,9 @@ OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend(
82 token2id_ = ReadTokens(is); 86 token2id_ = ReadTokens(is);
83 } 87 }
84 88
85 -#if __ANDROID_API__ >= 9 89 +template <typename Manager>
86 OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend( 90 OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend(
87 - AAssetManager *mgr, const std::string &tokens, 91 + Manager *mgr, const std::string &tokens,
88 const OfflineTtsVitsModelMetaData &meta_data) 92 const OfflineTtsVitsModelMetaData &meta_data)
89 : meta_data_(meta_data) { 93 : meta_data_(meta_data) {
90 auto buf = ReadFile(mgr, tokens); 94 auto buf = ReadFile(mgr, tokens);
@@ -92,8 +96,6 @@ OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend( @@ -92,8 +96,6 @@ OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend(
92 token2id_ = ReadTokens(is); 96 token2id_ = ReadTokens(is);
93 } 97 }
94 98
95 -#endif  
96 -  
97 std::vector<TokenIDs> OfflineTtsCharacterFrontend::ConvertTextToTokenIds( 99 std::vector<TokenIDs> OfflineTtsCharacterFrontend::ConvertTextToTokenIds(
98 const std::string &_text, const std::string & /*voice = ""*/) const { 100 const std::string &_text, const std::string & /*voice = ""*/) const {
99 // see 101 // see
@@ -189,4 +191,18 @@ std::vector<TokenIDs> OfflineTtsCharacterFrontend::ConvertTextToTokenIds( @@ -189,4 +191,18 @@ std::vector<TokenIDs> OfflineTtsCharacterFrontend::ConvertTextToTokenIds(
189 return ans; 191 return ans;
190 } 192 }
191 193
  194 +#if __ANDROID_API__ >= 9
  195 +template OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend(
  196 + AAssetManager *mgr, const std::string &tokens,
  197 + const OfflineTtsVitsModelMetaData &meta_data);
  198 +
  199 +#endif
  200 +
  201 +#if __OHOS__
  202 +template OfflineTtsCharacterFrontend::OfflineTtsCharacterFrontend(
  203 + NativeResourceManager *mgr, const std::string &tokens,
  204 + const OfflineTtsVitsModelMetaData &meta_data);
  205 +
  206 +#endif
  207 +
192 } // namespace sherpa_onnx 208 } // namespace sherpa_onnx
@@ -9,11 +9,6 @@ @@ -9,11 +9,6 @@
9 #include <unordered_map> 9 #include <unordered_map>
10 #include <vector> 10 #include <vector>
11 11
12 -#if __ANDROID_API__ >= 9  
13 -#include "android/asset_manager.h"  
14 -#include "android/asset_manager_jni.h"  
15 -#endif  
16 -  
17 #include "sherpa-onnx/csrc/offline-tts-frontend.h" 12 #include "sherpa-onnx/csrc/offline-tts-frontend.h"
18 #include "sherpa-onnx/csrc/offline-tts-vits-model-metadata.h" 13 #include "sherpa-onnx/csrc/offline-tts-vits-model-metadata.h"
19 14
@@ -24,11 +19,10 @@ class OfflineTtsCharacterFrontend : public OfflineTtsFrontend { @@ -24,11 +19,10 @@ class OfflineTtsCharacterFrontend : public OfflineTtsFrontend {
24 OfflineTtsCharacterFrontend(const std::string &tokens, 19 OfflineTtsCharacterFrontend(const std::string &tokens,
25 const OfflineTtsVitsModelMetaData &meta_data); 20 const OfflineTtsVitsModelMetaData &meta_data);
26 21
27 -#if __ANDROID_API__ >= 9  
28 - OfflineTtsCharacterFrontend(AAssetManager *mgr, const std::string &tokens, 22 + template <typename Manager>
  23 + OfflineTtsCharacterFrontend(Manager *mgr, const std::string &tokens,
29 const OfflineTtsVitsModelMetaData &meta_data); 24 const OfflineTtsVitsModelMetaData &meta_data);
30 25
31 -#endif  
32 /** Convert a string to token IDs. 26 /** Convert a string to token IDs.
33 * 27 *
34 * @param text The input text. 28 * @param text The input text.
@@ -6,6 +6,15 @@ @@ -6,6 +6,15 @@
6 6
7 #include <memory> 7 #include <memory>
8 8
  9 +#if __ANDROID_API__ >= 9
  10 +#include "android/asset_manager.h"
  11 +#include "android/asset_manager_jni.h"
  12 +#endif
  13 +
  14 +#if __OHOS__
  15 +#include "rawfile/raw_file_manager.h"
  16 +#endif
  17 +
9 #include "sherpa-onnx/csrc/offline-tts-vits-impl.h" 18 #include "sherpa-onnx/csrc/offline-tts-vits-impl.h"
10 19
11 namespace sherpa_onnx { 20 namespace sherpa_onnx {
@@ -16,12 +25,21 @@ std::unique_ptr<OfflineTtsImpl> OfflineTtsImpl::Create( @@ -16,12 +25,21 @@ std::unique_ptr<OfflineTtsImpl> OfflineTtsImpl::Create(
16 return std::make_unique<OfflineTtsVitsImpl>(config); 25 return std::make_unique<OfflineTtsVitsImpl>(config);
17 } 26 }
18 27
19 -#if __ANDROID_API__ >= 9 28 +template <typename Manager>
20 std::unique_ptr<OfflineTtsImpl> OfflineTtsImpl::Create( 29 std::unique_ptr<OfflineTtsImpl> OfflineTtsImpl::Create(
21 - AAssetManager *mgr, const OfflineTtsConfig &config) { 30 + Manager *mgr, const OfflineTtsConfig &config) {
22 // TODO(fangjun): Support other types 31 // TODO(fangjun): Support other types
23 return std::make_unique<OfflineTtsVitsImpl>(mgr, config); 32 return std::make_unique<OfflineTtsVitsImpl>(mgr, config);
24 } 33 }
  34 +
  35 +#if __ANDROID_API__ >= 9
  36 +template std::unique_ptr<OfflineTtsImpl> OfflineTtsImpl::Create(
  37 + AAssetManager *mgr, const OfflineTtsConfig &config);
  38 +#endif
  39 +
  40 +#if __OHOS__
  41 +template std::unique_ptr<OfflineTtsImpl> OfflineTtsImpl::Create(
  42 + NativeResourceManager *mgr, const OfflineTtsConfig &config);
25 #endif 43 #endif
26 44
27 } // namespace sherpa_onnx 45 } // namespace sherpa_onnx
@@ -8,11 +8,6 @@ @@ -8,11 +8,6 @@
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 10
11 -#if __ANDROID_API__ >= 9  
12 -#include "android/asset_manager.h"  
13 -#include "android/asset_manager_jni.h"  
14 -#endif  
15 -  
16 #include "sherpa-onnx/csrc/offline-tts.h" 11 #include "sherpa-onnx/csrc/offline-tts.h"
17 12
18 namespace sherpa_onnx { 13 namespace sherpa_onnx {
@@ -23,10 +18,9 @@ class OfflineTtsImpl { @@ -23,10 +18,9 @@ class OfflineTtsImpl {
23 18
24 static std::unique_ptr<OfflineTtsImpl> Create(const OfflineTtsConfig &config); 19 static std::unique_ptr<OfflineTtsImpl> Create(const OfflineTtsConfig &config);
25 20
26 -#if __ANDROID_API__ >= 9  
27 - static std::unique_ptr<OfflineTtsImpl> Create(AAssetManager *mgr, 21 + template <typename Manager>
  22 + static std::unique_ptr<OfflineTtsImpl> Create(Manager *mgr,
28 const OfflineTtsConfig &config); 23 const OfflineTtsConfig &config);
29 -#endif  
30 24
31 virtual GeneratedAudio Generate( 25 virtual GeneratedAudio Generate(
32 const std::string &text, int64_t sid = 0, float speed = 1.0, 26 const std::string &text, int64_t sid = 0, float speed = 1.0,
@@ -6,16 +6,10 @@ @@ -6,16 +6,10 @@
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
  9 +#include <strstream>
9 #include <utility> 10 #include <utility>
10 #include <vector> 11 #include <vector>
11 12
12 -#if __ANDROID_API__ >= 9  
13 -#include <strstream>  
14 -  
15 -#include "android/asset_manager.h"  
16 -#include "android/asset_manager_jni.h"  
17 -#endif  
18 -  
19 #include "fst/extensions/far/far.h" 13 #include "fst/extensions/far/far.h"
20 #include "kaldifst/csrc/kaldi-fst-io.h" 14 #include "kaldifst/csrc/kaldi-fst-io.h"
21 #include "kaldifst/csrc/text-normalizer.h" 15 #include "kaldifst/csrc/text-normalizer.h"
@@ -82,8 +76,8 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl { @@ -82,8 +76,8 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl {
82 } 76 }
83 } 77 }
84 78
85 -#if __ANDROID_API__ >= 9  
86 - OfflineTtsVitsImpl(AAssetManager *mgr, const OfflineTtsConfig &config) 79 + template <typename Manager>
  80 + OfflineTtsVitsImpl(Manager *mgr, const OfflineTtsConfig &config)
87 : config_(config), 81 : config_(config),
88 model_(std::make_unique<OfflineTtsVitsModel>(mgr, config.model)) { 82 model_(std::make_unique<OfflineTtsVitsModel>(mgr, config.model)) {
89 InitFrontend(mgr); 83 InitFrontend(mgr);
@@ -130,7 +124,6 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl { @@ -130,7 +124,6 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl {
130 } // for (const auto &f : files) 124 } // for (const auto &f : files)
131 } // if (!config.rule_fars.empty()) 125 } // if (!config.rule_fars.empty())
132 } 126 }
133 -#endif  
134 127
135 int32_t SampleRate() const override { 128 int32_t SampleRate() const override {
136 return model_->GetMetaData().sample_rate; 129 return model_->GetMetaData().sample_rate;
@@ -297,8 +290,8 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl { @@ -297,8 +290,8 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl {
297 } 290 }
298 291
299 private: 292 private:
300 -#if __ANDROID_API__ >= 9  
301 - void InitFrontend(AAssetManager *mgr) { 293 + template <typename Manager>
  294 + void InitFrontend(Manager *mgr) {
302 const auto &meta_data = model_->GetMetaData(); 295 const auto &meta_data = model_->GetMetaData();
303 296
304 if (meta_data.frontend == "characters") { 297 if (meta_data.frontend == "characters") {
@@ -323,7 +316,6 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl { @@ -323,7 +316,6 @@ class OfflineTtsVitsImpl : public OfflineTtsImpl {
323 meta_data.punctuations, meta_data.language, config_.model.debug); 316 meta_data.punctuations, meta_data.language, config_.model.debug);
324 } 317 }
325 } 318 }
326 -#endif  
327 319
328 void InitFrontend() { 320 void InitFrontend() {
329 const auto &meta_data = model_->GetMetaData(); 321 const auto &meta_data = model_->GetMetaData();
@@ -9,6 +9,15 @@ @@ -9,6 +9,15 @@
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
  12 +#if __ANDROID_API__ >= 9
  13 +#include "android/asset_manager.h"
  14 +#include "android/asset_manager_jni.h"
  15 +#endif
  16 +
  17 +#if __OHOS__
  18 +#include "rawfile/raw_file_manager.h"
  19 +#endif
  20 +
12 #include "sherpa-onnx/csrc/macros.h" 21 #include "sherpa-onnx/csrc/macros.h"
13 #include "sherpa-onnx/csrc/onnx-utils.h" 22 #include "sherpa-onnx/csrc/onnx-utils.h"
14 #include "sherpa-onnx/csrc/session.h" 23 #include "sherpa-onnx/csrc/session.h"
@@ -26,8 +35,8 @@ class OfflineTtsVitsModel::Impl { @@ -26,8 +35,8 @@ class OfflineTtsVitsModel::Impl {
26 Init(buf.data(), buf.size()); 35 Init(buf.data(), buf.size());
27 } 36 }
28 37
29 -#if __ANDROID_API__ >= 9  
30 - Impl(AAssetManager *mgr, const OfflineTtsModelConfig &config) 38 + template <typename Manager>
  39 + Impl(Manager *mgr, const OfflineTtsModelConfig &config)
31 : config_(config), 40 : config_(config),
32 env_(ORT_LOGGING_LEVEL_ERROR), 41 env_(ORT_LOGGING_LEVEL_ERROR),
33 sess_opts_(GetSessionOptions(config)), 42 sess_opts_(GetSessionOptions(config)),
@@ -35,7 +44,6 @@ class OfflineTtsVitsModel::Impl { @@ -35,7 +44,6 @@ class OfflineTtsVitsModel::Impl {
35 auto buf = ReadFile(mgr, config.vits.model); 44 auto buf = ReadFile(mgr, config.vits.model);
36 Init(buf.data(), buf.size()); 45 Init(buf.data(), buf.size());
37 } 46 }
38 -#endif  
39 47
40 Ort::Value Run(Ort::Value x, int64_t sid, float speed) { 48 Ort::Value Run(Ort::Value x, int64_t sid, float speed) {
41 if (meta_data_.is_piper || meta_data_.is_coqui) { 49 if (meta_data_.is_piper || meta_data_.is_coqui) {
@@ -336,11 +344,10 @@ class OfflineTtsVitsModel::Impl { @@ -336,11 +344,10 @@ class OfflineTtsVitsModel::Impl {
336 OfflineTtsVitsModel::OfflineTtsVitsModel(const OfflineTtsModelConfig &config) 344 OfflineTtsVitsModel::OfflineTtsVitsModel(const OfflineTtsModelConfig &config)
337 : impl_(std::make_unique<Impl>(config)) {} 345 : impl_(std::make_unique<Impl>(config)) {}
338 346
339 -#if __ANDROID_API__ >= 9  
340 -OfflineTtsVitsModel::OfflineTtsVitsModel(AAssetManager *mgr, 347 +template <typename Manager>
  348 +OfflineTtsVitsModel::OfflineTtsVitsModel(Manager *mgr,
341 const OfflineTtsModelConfig &config) 349 const OfflineTtsModelConfig &config)
342 : impl_(std::make_unique<Impl>(mgr, config)) {} 350 : impl_(std::make_unique<Impl>(mgr, config)) {}
343 -#endif  
344 351
345 OfflineTtsVitsModel::~OfflineTtsVitsModel() = default; 352 OfflineTtsVitsModel::~OfflineTtsVitsModel() = default;
346 353
@@ -359,4 +366,14 @@ const OfflineTtsVitsModelMetaData &OfflineTtsVitsModel::GetMetaData() const { @@ -359,4 +366,14 @@ const OfflineTtsVitsModelMetaData &OfflineTtsVitsModel::GetMetaData() const {
359 return impl_->GetMetaData(); 366 return impl_->GetMetaData();
360 } 367 }
361 368
  369 +#if __ANDROID_API__ >= 9
  370 +template OfflineTtsVitsModel::OfflineTtsVitsModel(
  371 + AAssetManager *mgr, const OfflineTtsModelConfig &config);
  372 +#endif
  373 +
  374 +#if __OHOS__
  375 +template OfflineTtsVitsModel::OfflineTtsVitsModel(
  376 + NativeResourceManager *mgr, const OfflineTtsModelConfig &config);
  377 +#endif
  378 +
362 } // namespace sherpa_onnx 379 } // namespace sherpa_onnx
@@ -8,11 +8,6 @@ @@ -8,11 +8,6 @@
8 #include <memory> 8 #include <memory>
9 #include <string> 9 #include <string>
10 10
11 -#if __ANDROID_API__ >= 9  
12 -#include "android/asset_manager.h"  
13 -#include "android/asset_manager_jni.h"  
14 -#endif  
15 -  
16 #include "onnxruntime_cxx_api.h" // NOLINT 11 #include "onnxruntime_cxx_api.h" // NOLINT
17 #include "sherpa-onnx/csrc/offline-tts-model-config.h" 12 #include "sherpa-onnx/csrc/offline-tts-model-config.h"
18 #include "sherpa-onnx/csrc/offline-tts-vits-model-metadata.h" 13 #include "sherpa-onnx/csrc/offline-tts-vits-model-metadata.h"
@@ -24,9 +19,9 @@ class OfflineTtsVitsModel { @@ -24,9 +19,9 @@ class OfflineTtsVitsModel {
24 ~OfflineTtsVitsModel(); 19 ~OfflineTtsVitsModel();
25 20
26 explicit OfflineTtsVitsModel(const OfflineTtsModelConfig &config); 21 explicit OfflineTtsVitsModel(const OfflineTtsModelConfig &config);
27 -#if __ANDROID_API__ >= 9  
28 - OfflineTtsVitsModel(AAssetManager *mgr, const OfflineTtsModelConfig &config);  
29 -#endif 22 +
  23 + template <typename Manager>
  24 + OfflineTtsVitsModel(Manager *mgr, const OfflineTtsModelConfig &config);
30 25
31 /** Run the model. 26 /** Run the model.
32 * 27 *
@@ -7,6 +7,15 @@ @@ -7,6 +7,15 @@
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
  10 +#if __ANDROID_API__ >= 9
  11 +#include "android/asset_manager.h"
  12 +#include "android/asset_manager_jni.h"
  13 +#endif
  14 +
  15 +#if __OHOS__
  16 +#include "rawfile/raw_file_manager.h"
  17 +#endif
  18 +
10 #include "sherpa-onnx/csrc/file-utils.h" 19 #include "sherpa-onnx/csrc/file-utils.h"
11 #include "sherpa-onnx/csrc/macros.h" 20 #include "sherpa-onnx/csrc/macros.h"
12 #include "sherpa-onnx/csrc/offline-tts-impl.h" 21 #include "sherpa-onnx/csrc/offline-tts-impl.h"
@@ -78,10 +87,9 @@ std::string OfflineTtsConfig::ToString() const { @@ -78,10 +87,9 @@ std::string OfflineTtsConfig::ToString() const {
78 OfflineTts::OfflineTts(const OfflineTtsConfig &config) 87 OfflineTts::OfflineTts(const OfflineTtsConfig &config)
79 : impl_(OfflineTtsImpl::Create(config)) {} 88 : impl_(OfflineTtsImpl::Create(config)) {}
80 89
81 -#if __ANDROID_API__ >= 9  
82 -OfflineTts::OfflineTts(AAssetManager *mgr, const OfflineTtsConfig &config) 90 +template <typename Manager>
  91 +OfflineTts::OfflineTts(Manager *mgr, const OfflineTtsConfig &config)
83 : impl_(OfflineTtsImpl::Create(mgr, config)) {} 92 : impl_(OfflineTtsImpl::Create(mgr, config)) {}
84 -#endif  
85 93
86 OfflineTts::~OfflineTts() = default; 94 OfflineTts::~OfflineTts() = default;
87 95
@@ -95,4 +103,14 @@ int32_t OfflineTts::SampleRate() const { return impl_->SampleRate(); } @@ -95,4 +103,14 @@ int32_t OfflineTts::SampleRate() const { return impl_->SampleRate(); }
95 103
96 int32_t OfflineTts::NumSpeakers() const { return impl_->NumSpeakers(); } 104 int32_t OfflineTts::NumSpeakers() const { return impl_->NumSpeakers(); }
97 105
  106 +#if __ANDROID_API__ >= 9
  107 +template OfflineTts::OfflineTts(AAssetManager *mgr,
  108 + const OfflineTtsConfig &config);
  109 +#endif
  110 +
  111 +#if __OHOS__
  112 +template OfflineTts::OfflineTts(NativeResourceManager *mgr,
  113 + const OfflineTtsConfig &config);
  114 +#endif
  115 +
98 } // namespace sherpa_onnx 116 } // namespace sherpa_onnx
@@ -10,11 +10,6 @@ @@ -10,11 +10,6 @@
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 -#if __ANDROID_API__ >= 9  
14 -#include "android/asset_manager.h"  
15 -#include "android/asset_manager_jni.h"  
16 -#endif  
17 -  
18 #include "sherpa-onnx/csrc/offline-tts-model-config.h" 13 #include "sherpa-onnx/csrc/offline-tts-model-config.h"
19 #include "sherpa-onnx/csrc/parse-options.h" 14 #include "sherpa-onnx/csrc/parse-options.h"
20 15
@@ -69,9 +64,8 @@ class OfflineTts { @@ -69,9 +64,8 @@ class OfflineTts {
69 ~OfflineTts(); 64 ~OfflineTts();
70 explicit OfflineTts(const OfflineTtsConfig &config); 65 explicit OfflineTts(const OfflineTtsConfig &config);
71 66
72 -#if __ANDROID_API__ >= 9  
73 - OfflineTts(AAssetManager *mgr, const OfflineTtsConfig &config);  
74 -#endif 67 + template <typename Manager>
  68 + OfflineTts(Manager *mgr, const OfflineTtsConfig &config);
75 69
76 // @param text A string containing words separated by spaces 70 // @param text A string containing words separated by spaces
77 // @param sid Speaker ID. Used only for multi-speaker models, e.g., models 71 // @param sid Speaker ID. Used only for multi-speaker models, e.g., models
@@ -11,16 +11,19 @@ @@ -11,16 +11,19 @@
11 #include <mutex> // NOLINT 11 #include <mutex> // NOLINT
12 #include <sstream> 12 #include <sstream>
13 #include <string> 13 #include <string>
  14 +#include <strstream>
14 #include <utility> 15 #include <utility>
15 #include <vector> 16 #include <vector>
16 17
17 #if __ANDROID_API__ >= 9 18 #if __ANDROID_API__ >= 9
18 -#include <strstream>  
19 -  
20 #include "android/asset_manager.h" 19 #include "android/asset_manager.h"
21 #include "android/asset_manager_jni.h" 20 #include "android/asset_manager_jni.h"
22 #endif 21 #endif
23 22
  23 +#if __OHOS__
  24 +#include "rawfile/raw_file_manager.h"
  25 +#endif
  26 +
24 #include "espeak-ng/speak_lib.h" 27 #include "espeak-ng/speak_lib.h"
25 #include "phoneme_ids.hpp" 28 #include "phoneme_ids.hpp"
26 #include "phonemize.hpp" 29 #include "phonemize.hpp"
@@ -196,9 +199,9 @@ PiperPhonemizeLexicon::PiperPhonemizeLexicon( @@ -196,9 +199,9 @@ PiperPhonemizeLexicon::PiperPhonemizeLexicon(
196 InitEspeak(data_dir); 199 InitEspeak(data_dir);
197 } 200 }
198 201
199 -#if __ANDROID_API__ >= 9 202 +template <typename Manager>
200 PiperPhonemizeLexicon::PiperPhonemizeLexicon( 203 PiperPhonemizeLexicon::PiperPhonemizeLexicon(
201 - AAssetManager *mgr, const std::string &tokens, const std::string &data_dir, 204 + Manager *mgr, const std::string &tokens, const std::string &data_dir,
202 const OfflineTtsVitsModelMetaData &meta_data) 205 const OfflineTtsVitsModelMetaData &meta_data)
203 : meta_data_(meta_data) { 206 : meta_data_(meta_data) {
204 { 207 {
@@ -212,7 +215,6 @@ PiperPhonemizeLexicon::PiperPhonemizeLexicon( @@ -212,7 +215,6 @@ PiperPhonemizeLexicon::PiperPhonemizeLexicon(
212 // data_dir. 215 // data_dir.
213 InitEspeak(data_dir); 216 InitEspeak(data_dir);
214 } 217 }
215 -#endif  
216 218
217 std::vector<TokenIDs> PiperPhonemizeLexicon::ConvertTextToTokenIds( 219 std::vector<TokenIDs> PiperPhonemizeLexicon::ConvertTextToTokenIds(
218 const std::string &text, const std::string &voice /*= ""*/) const { 220 const std::string &text, const std::string &voice /*= ""*/) const {
@@ -255,4 +257,16 @@ std::vector<TokenIDs> PiperPhonemizeLexicon::ConvertTextToTokenIds( @@ -255,4 +257,16 @@ std::vector<TokenIDs> PiperPhonemizeLexicon::ConvertTextToTokenIds(
255 return ans; 257 return ans;
256 } 258 }
257 259
  260 +#if __ANDROID_API__ >= 9
  261 +template PiperPhonemizeLexicon::PiperPhonemizeLexicon(
  262 + AAssetManager *mgr, const std::string &tokens, const std::string &data_dir,
  263 + const OfflineTtsVitsModelMetaData &meta_data);
  264 +#endif
  265 +
  266 +#if __OHOS__
  267 +template PiperPhonemizeLexicon::PiperPhonemizeLexicon(
  268 + NativeResourceManager *mgr, const std::string &tokens,
  269 + const std::string &data_dir, const OfflineTtsVitsModelMetaData &meta_data);
  270 +#endif
  271 +
258 } // namespace sherpa_onnx 272 } // namespace sherpa_onnx
@@ -9,11 +9,6 @@ @@ -9,11 +9,6 @@
9 #include <unordered_map> 9 #include <unordered_map>
10 #include <vector> 10 #include <vector>
11 11
12 -#if __ANDROID_API__ >= 9  
13 -#include "android/asset_manager.h"  
14 -#include "android/asset_manager_jni.h"  
15 -#endif  
16 -  
17 #include "sherpa-onnx/csrc/offline-tts-frontend.h" 12 #include "sherpa-onnx/csrc/offline-tts-frontend.h"
18 #include "sherpa-onnx/csrc/offline-tts-vits-model-metadata.h" 13 #include "sherpa-onnx/csrc/offline-tts-vits-model-metadata.h"
19 14
@@ -24,11 +19,10 @@ class PiperPhonemizeLexicon : public OfflineTtsFrontend { @@ -24,11 +19,10 @@ class PiperPhonemizeLexicon : public OfflineTtsFrontend {
24 PiperPhonemizeLexicon(const std::string &tokens, const std::string &data_dir, 19 PiperPhonemizeLexicon(const std::string &tokens, const std::string &data_dir,
25 const OfflineTtsVitsModelMetaData &meta_data); 20 const OfflineTtsVitsModelMetaData &meta_data);
26 21
27 -#if __ANDROID_API__ >= 9  
28 - PiperPhonemizeLexicon(AAssetManager *mgr, const std::string &tokens, 22 + template <typename Manager>
  23 + PiperPhonemizeLexicon(Manager *mgr, const std::string &tokens,
29 const std::string &data_dir, 24 const std::string &data_dir,
30 const OfflineTtsVitsModelMetaData &meta_data); 25 const OfflineTtsVitsModelMetaData &meta_data);
31 -#endif  
32 26
33 std::vector<TokenIDs> ConvertTextToTokenIds( 27 std::vector<TokenIDs> ConvertTextToTokenIds(
34 const std::string &text, const std::string &voice = "") const override; 28 const std::string &text, const std::string &voice = "") const override;
@@ -51,11 +51,11 @@ class SileroVadModel::Impl { @@ -51,11 +51,11 @@ class SileroVadModel::Impl {
51 : config_(config), 51 : config_(config),
52 env_(ORT_LOGGING_LEVEL_ERROR), 52 env_(ORT_LOGGING_LEVEL_ERROR),
53 sess_opts_(GetSessionOptions(config)), 53 sess_opts_(GetSessionOptions(config)),
54 - allocator_{} { 54 + allocator_{},
  55 + sample_rate_(config.sample_rate) {
55 auto buf = ReadFile(mgr, config.silero_vad.model); 56 auto buf = ReadFile(mgr, config.silero_vad.model);
56 Init(buf.data(), buf.size()); 57 Init(buf.data(), buf.size());
57 58
58 - sample_rate_ = config.sample_rate;  
59 if (sample_rate_ != 16000) { 59 if (sample_rate_ != 16000) {
60 SHERPA_ONNX_LOGE("Expected sample rate 16000. Given: %d", 60 SHERPA_ONNX_LOGE("Expected sample rate 16000. Given: %d",
61 config.sample_rate); 61 config.sample_rate);