Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
xuning
/
sherpaonnx
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Fangjun Kuang
2024-04-22 17:21:05 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Committed by
GitHub
2024-04-22 17:21:05 +0800
Commit
7f3b9ffe5d4fd57fa2458ab26b13a99af5749a7e
7f3b9ffe
1 parent
494cb5c7
Refactor TTS Android code to support jieba for Chinese TTS models (#800)
隐藏空白字符变更
内嵌
并排对比
正在显示
40 个修改的文件
包含
352 行增加
和
285 行删除
.gitignore
android/SherpaOnnxTts/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt
android/SherpaOnnxTts/app/src/main/java/com/k2fsa/sherpa/onnx/Tts.kt
android/SherpaOnnxTtsEngine/app/src/main/java/com/k2fsa/sherpa/onnx/tts/engine/TtsEngine.kt
build-android-arm64-v8a.sh
build-android-armv7-eabi.sh
build-android-x86-64.sh
build-android-x86.sh
scripts/apk/build-apk-tts-engine.sh.in
scripts/apk/build-apk-tts.sh.in
scripts/apk/generate-tts-apk-script.py
sherpa-onnx/csrc/audio-tagging-model-config.cc
sherpa-onnx/csrc/audio-tagging.cc
sherpa-onnx/csrc/file-utils.cc
sherpa-onnx/csrc/jieba-lexicon.cc
sherpa-onnx/csrc/keyword-spotter.cc
sherpa-onnx/csrc/offline-ctc-fst-decoder-config.cc
sherpa-onnx/csrc/offline-lm-config.cc
sherpa-onnx/csrc/offline-nemo-enc-dec-ctc-model-config.cc
sherpa-onnx/csrc/offline-paraformer-model-config.cc
sherpa-onnx/csrc/offline-transducer-model-config.cc
sherpa-onnx/csrc/offline-tts-vits-model-config.cc
sherpa-onnx/csrc/offline-tts.cc
sherpa-onnx/csrc/offline-wenet-ctc-model-config.cc
sherpa-onnx/csrc/offline-whisper-model-config.cc
sherpa-onnx/csrc/offline-zipformer-audio-tagging-model-config.cc
sherpa-onnx/csrc/offline-zipformer-ctc-model-config.cc
sherpa-onnx/csrc/online-ctc-fst-decoder-config.cc
sherpa-onnx/csrc/online-lm-config.cc
sherpa-onnx/csrc/online-model-config.cc
sherpa-onnx/csrc/online-paraformer-model-config.cc
sherpa-onnx/csrc/online-transducer-model-config.cc
sherpa-onnx/csrc/online-wenet-ctc-model-config.cc
sherpa-onnx/csrc/online-zipformer2-ctc-model-config.cc
sherpa-onnx/csrc/silero-vad-model-config.cc
sherpa-onnx/csrc/speaker-embedding-extractor.cc
sherpa-onnx/csrc/spoken-language-identification.cc
sherpa-onnx/jni/CMakeLists.txt
sherpa-onnx/jni/jni.cc
sherpa-onnx/jni/offline-tts.cc
.gitignore
查看文件 @
7f3b9ff
...
...
@@ -93,3 +93,5 @@ sr-data
vits-icefall-*
sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12
spoken-language-identification-test-wavs
my-release-key*
vits-zh-hf-fanchen-C
...
...
android/SherpaOnnxTts/app/src/main/java/com/k2fsa/sherpa/onnx/MainActivity.kt
查看文件 @
7f3b9ff
...
...
@@ -158,6 +158,7 @@ class MainActivity : AppCompatActivity() {
var ruleFars: String?
var lexicon: String?
var dataDir: String?
var dictDir: String?
var assets: AssetManager? = application.assets
// The purpose of such a design is to make the CI test easier
...
...
@@ -169,6 +170,7 @@ class MainActivity : AppCompatActivity() {
ruleFars = null
lexicon = null
dataDir = null
dictDir = null
// Example 1:
// modelDir = "vits-vctk"
...
...
@@ -191,21 +193,36 @@ class MainActivity : AppCompatActivity() {
// lexicon = "lexicon.txt"
// Example 4:
// https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/vits.html#csukuangfj-vits-zh-hf-fanchen-c-chinese-187-speakers
// modelDir = "vits-zh-hf-fanchen-C"
// modelName = "vits-zh-hf-fanchen-C.onnx"
// lexicon = "lexicon.txt"
// dictDir = "vits-zh-hf-fanchen-C/dict"
// Example 5:
// https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-coqui-de-css10.tar.bz2
// modelDir = "vits-coqui-de-css10"
// modelName = "model.onnx"
// lang = "deu"
if (dataDir != null) {
val newDir = copyDataDir(modelDir)
val newDir = copyDataDir(modelDir
!!
)
modelDir = newDir + "/" + modelDir
dataDir = newDir + "/" + dataDir
assets = null
}
if (dictDir != null) {
val newDir = copyDataDir( modelDir!!)
modelDir = newDir + "/" + modelDir
dictDir = modelDir + "/" + "dict"
ruleFsts = "$modelDir/phone.fst,$modelDir/date.fst,$modelDir/number.fst"
assets = null
}
val config = getOfflineTtsConfig(
modelDir = modelDir!!, modelName = modelName!!, lexicon = lexicon ?: "",
dataDir = dataDir ?: "",
dictDir = dictDir ?: "",
ruleFsts = ruleFsts ?: "",
ruleFars = ruleFars ?: "",
)!!
...
...
android/SherpaOnnxTts/app/src/main/java/com/k2fsa/sherpa/onnx/Tts.kt
查看文件 @
7f3b9ff
...
...
@@ -8,6 +8,7 @@ data class OfflineTtsVitsModelConfig(
var lexicon: String = "",
var tokens: String,
var dataDir: String = "",
var dictDir: String = "",
var noiseScale: Float = 0.667f,
var noiseScaleW: Float = 0.8f,
var lengthScale: Float = 1.0f,
...
...
@@ -49,7 +50,7 @@ class OfflineTts(
init {
if (assetManager != null) {
ptr = new(assetManager, config)
ptr = new
FromAsset
(assetManager, config)
} else {
ptr = newFromFile(config)
}
...
...
@@ -87,7 +88,7 @@ class OfflineTts(
fun allocate(assetManager: AssetManager? = null) {
if (ptr == 0L) {
if (assetManager != null) {
ptr = new(assetManager, config)
ptr = new
FromAsset
(assetManager, config)
} else {
ptr = newFromFile(config)
}
...
...
@@ -105,7 +106,7 @@ class OfflineTts(
delete(ptr)
}
private external fun new(
private external fun new
FromAsset
(
assetManager: AssetManager,
config: OfflineTtsConfig,
): Long
...
...
@@ -152,6 +153,7 @@ fun getOfflineTtsConfig(
modelName: String,
lexicon: String,
dataDir: String,
dictDir: String,
ruleFsts: String,
ruleFars: String
): OfflineTtsConfig? {
...
...
@@ -161,7 +163,8 @@ fun getOfflineTtsConfig(
model = "$modelDir/$modelName",
lexicon = "$modelDir/$lexicon",
tokens = "$modelDir/tokens.txt",
dataDir = "$dataDir"
dataDir = dataDir,
dictDir = dictDir,
),
numThreads = 2,
debug = true,
...
...
android/SherpaOnnxTtsEngine/app/src/main/java/com/k2fsa/sherpa/onnx/tts/engine/TtsEngine.kt
查看文件 @
7f3b9ff
...
...
@@ -42,6 +42,7 @@ object TtsEngine {
private var ruleFars: String? = null
private var lexicon: String? = null
private var dataDir: String? = null
private var dictDir: String? = null
private var assets: AssetManager? = null
init {
...
...
@@ -54,6 +55,7 @@ object TtsEngine {
ruleFars = null
lexicon = null
dataDir = null
dictDir = null
lang = null
// Please enable one and only one of the examples below
...
...
@@ -83,6 +85,14 @@ object TtsEngine {
// lang = "zho"
// Example 4:
// https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/vits.html#csukuangfj-vits-zh-hf-fanchen-c-chinese-187-speakers
// modelDir = "vits-zh-hf-fanchen-C"
// modelName = "vits-zh-hf-fanchen-C.onnx"
// lexicon = "lexicon.txt"
// dictDir = "vits-zh-hf-fanchen-C/dict"
// lang = "zho"
// Example 5:
// https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-coqui-de-css10.tar.bz2
// This model does not need lexicon or dataDir
// modelDir = "vits-coqui-de-css10"
...
...
@@ -108,9 +118,18 @@ object TtsEngine {
assets = null
}
if (dictDir != null) {
val newDir = copyDataDir(context, modelDir!!)
modelDir = newDir + "/" + modelDir
dictDir = modelDir + "/" + "dict"
ruleFsts = "$modelDir/phone.fst,$modelDir/date.fst,$modelDir/number.fst"
assets = null
}
val config = getOfflineTtsConfig(
modelDir = modelDir!!, modelName = modelName!!, lexicon = lexicon ?: "",
dataDir = dataDir ?: "",
dictDir = dictDir ?: "",
ruleFsts = ruleFsts ?: "",
ruleFars = ruleFars ?: ""
)!!
...
...
build-android-arm64-v8a.sh
查看文件 @
7f3b9ff
...
...
@@ -47,7 +47,7 @@ onnxruntime_version=1.17.1
if
[
! -f
$onnxruntime_version
/jni/arm64-v8a/libonnxruntime.so
]
;
then
mkdir -p
$onnxruntime_version
pushd
$onnxruntime_version
wget -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
wget -
c -
q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
unzip onnxruntime-android-
${
onnxruntime_version
}
.zip
rm onnxruntime-android-
${
onnxruntime_version
}
.zip
popd
...
...
build-android-armv7-eabi.sh
查看文件 @
7f3b9ff
...
...
@@ -48,7 +48,7 @@ onnxruntime_version=1.17.1
if
[
! -f
$onnxruntime_version
/jni/armeabi-v7a/libonnxruntime.so
]
;
then
mkdir -p
$onnxruntime_version
pushd
$onnxruntime_version
wget -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
wget -
c -
q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
unzip onnxruntime-android-
${
onnxruntime_version
}
.zip
rm onnxruntime-android-
${
onnxruntime_version
}
.zip
popd
...
...
build-android-x86-64.sh
查看文件 @
7f3b9ff
...
...
@@ -48,7 +48,7 @@ onnxruntime_version=1.17.1
if
[
! -f
$onnxruntime_version
/jni/x86_64/libonnxruntime.so
]
;
then
mkdir -p
$onnxruntime_version
pushd
$onnxruntime_version
wget -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
wget -
c -
q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
unzip onnxruntime-android-
${
onnxruntime_version
}
.zip
rm onnxruntime-android-
${
onnxruntime_version
}
.zip
popd
...
...
build-android-x86.sh
查看文件 @
7f3b9ff
...
...
@@ -48,7 +48,7 @@ onnxruntime_version=1.17.1
if
[
! -f
$onnxruntime_version
/jni/x86/libonnxruntime.so
]
;
then
mkdir -p
$onnxruntime_version
pushd
$onnxruntime_version
wget -q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
wget -
c -
q https://github.com/csukuangfj/onnxruntime-libs/releases/download/v
${
onnxruntime_version
}
/onnxruntime-android-
${
onnxruntime_version
}
.zip
unzip onnxruntime-android-
${
onnxruntime_version
}
.zip
rm onnxruntime-android-
${
onnxruntime_version
}
.zip
popd
...
...
scripts/apk/build-apk-tts-engine.sh.in
查看文件 @
7f3b9ff
...
...
@@ -61,6 +61,11 @@ sed -i.bak s/"lang = null"/"lang = \"$lang_iso_639_3\""/ ./TtsEngine.kt
sed -i.bak s%
"ruleFsts = null"
%
"ruleFars =
\"
$rule_fars
\"
"
% ./TtsEngine.kt
{%
endif %
}
{%
if
tts_model.dict_dir %
}
dict_dir
={{
tts_model.dict_dir
}}
sed -i.bak s%
"dictDir = null"
%
"dictDir =
\"
$dict_dir
\"
"
% ./TtsEngine.kt
{%
endif %
}
{%
if
tts_model.data_dir %
}
data_dir
={{
tts_model.data_dir
}}
sed -i.bak s%
"dataDir = null"
%
"dataDir =
\"
$data_dir
\"
"
% ./TtsEngine.kt
...
...
scripts/apk/build-apk-tts.sh.in
查看文件 @
7f3b9ff
...
...
@@ -59,6 +59,11 @@ sed -i.bak s/"modelName = null"/"modelName = \"$model_name\""/ ./MainActivity.kt
sed -i.bak s%
"ruleFsts = null"
%
"ruleFars =
\"
$rule_fars
\"
"
% ./MainActivity.kt
{%
endif %
}
{%
if
tts_model.dict_dir %
}
dict_dir
={{
tts_model.dict_dir
}}
sed -i.bak s%
"dictDir = null"
%
"dictDir =
\"
$dict_dir
\"
"
% ./MainActivity.kt
{%
endif %
}
{%
if
tts_model.data_dir %
}
data_dir
={{
tts_model.data_dir
}}
sed -i.bak s%
"dataDir = null"
%
"dataDir =
\"
$data_dir
\"
"
% ./MainActivity.kt
...
...
scripts/apk/generate-tts-apk-script.py
查看文件 @
7f3b9ff
...
...
@@ -35,6 +35,7 @@ class TtsModel:
rule_fsts
:
Optional
[
List
[
str
]]
=
None
rule_fars
:
Optional
[
List
[
str
]]
=
None
data_dir
:
Optional
[
str
]
=
None
dict_dir
:
Optional
[
str
]
=
None
is_char
:
bool
=
False
lang_iso_639_3
:
str
=
""
...
...
@@ -326,8 +327,14 @@ def get_vits_models() -> List[TtsModel]:
rule_fsts
=
[
"phone.fst"
,
"date.fst"
,
"number.fst"
,
"new_heteronym.fst"
]
for
m
in
chinese_models
:
s
=
[
f
"{m.model_dir}/{r}"
for
r
in
rule_fsts
]
if
"vits-zh-hf"
in
m
.
model_dir
:
s
=
s
[:
-
1
]
m
.
dict_dir
=
m
.
model_dir
+
"/dict"
m
.
rule_fsts
=
","
.
join
(
s
)
m
.
rule_fars
=
f
"{m.model_dir}/rule.far"
if
"vits-zh-hf"
not
in
m
.
model_dir
:
m
.
rule_fars
=
f
"{m.model_dir}/rule.far"
all_models
=
chinese_models
+
[
TtsModel
(
...
...
sherpa-onnx/csrc/audio-tagging-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -32,7 +32,7 @@ bool AudioTaggingModelConfig::Validate() const {
}
if
(
!
ced
.
empty
()
&&
!
FileExists
(
ced
))
{
SHERPA_ONNX_LOGE
(
"CED model file
%s
does not exist"
,
ced
.
c_str
());
SHERPA_ONNX_LOGE
(
"CED model file
'%s'
does not exist"
,
ced
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/audio-tagging.cc
查看文件 @
7f3b9ff
...
...
@@ -48,7 +48,7 @@ bool AudioTaggingConfig::Validate() const {
}
if
(
!
FileExists
(
labels
))
{
SHERPA_ONNX_LOGE
(
"--labels
%s
does not exist"
,
labels
.
c_str
());
SHERPA_ONNX_LOGE
(
"--labels
'%s'
does not exist"
,
labels
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/file-utils.cc
查看文件 @
7f3b9ff
...
...
@@ -7,7 +7,7 @@
#include <fstream>
#include <string>
#include "sherpa-onnx/csrc/
log
.h"
#include "sherpa-onnx/csrc/
macros
.h"
namespace
sherpa_onnx
{
...
...
@@ -17,7 +17,7 @@ bool FileExists(const std::string &filename) {
void
AssertFileExists
(
const
std
::
string
&
filename
)
{
if
(
!
FileExists
(
filename
))
{
SHERPA_ONNX_LOG
(
FATAL
)
<<
filename
<<
" does not exist!"
;
SHERPA_ONNX_LOG
E
(
"filename '%s' does not exist"
,
filename
.
c_str
())
;
exit
(
-
1
);
}
}
...
...
sherpa-onnx/csrc/jieba-lexicon.cc
查看文件 @
7f3b9ff
...
...
@@ -146,6 +146,14 @@ class JiebaLexicon::Impl {
if
(
token2id_
.
count
(
p
.
first
)
&&
!
token2id_
.
count
(
p
.
second
))
{
token2id_
[
p
.
second
]
=
token2id_
[
p
.
first
];
}
if
(
!
token2id_
.
count
(
p
.
first
)
&&
token2id_
.
count
(
p
.
second
))
{
token2id_
[
p
.
first
]
=
token2id_
[
p
.
second
];
}
}
if
(
!
token2id_
.
count
(
"、"
)
&&
token2id_
.
count
(
","
))
{
token2id_
[
"、"
]
=
token2id_
[
","
];
}
}
...
...
sherpa-onnx/csrc/keyword-spotter.cc
查看文件 @
7f3b9ff
...
...
@@ -101,7 +101,8 @@ bool KeywordSpotterConfig::Validate() const {
// Solution: take keyword_file variable is directly
// parsed as a string of keywords
if
(
!
std
::
ifstream
(
keywords_file
.
c_str
()).
good
())
{
SHERPA_ONNX_LOGE
(
"Keywords file %s does not exist."
,
keywords_file
.
c_str
());
SHERPA_ONNX_LOGE
(
"Keywords file '%s' does not exist."
,
keywords_file
.
c_str
());
return
false
;
}
#endif
...
...
sherpa-onnx/csrc/offline-ctc-fst-decoder-config.cc
查看文件 @
7f3b9ff
...
...
@@ -34,7 +34,7 @@ void OfflineCtcFstDecoderConfig::Register(ParseOptions *po) {
bool
OfflineCtcFstDecoderConfig
::
Validate
()
const
{
if
(
!
graph
.
empty
()
&&
!
FileExists
(
graph
))
{
SHERPA_ONNX_LOGE
(
"graph:
%s
does not exist"
,
graph
.
c_str
());
SHERPA_ONNX_LOGE
(
"graph:
'%s'
does not exist"
,
graph
.
c_str
());
return
false
;
}
return
true
;
...
...
sherpa-onnx/csrc/offline-lm-config.cc
查看文件 @
7f3b9ff
...
...
@@ -22,7 +22,7 @@ void OfflineLMConfig::Register(ParseOptions *po) {
bool
OfflineLMConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-nemo-enc-dec-ctc-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -16,7 +16,7 @@ void OfflineNemoEncDecCtcModelConfig::Register(ParseOptions *po) {
bool
OfflineNemoEncDecCtcModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"NeMo model:
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"NeMo model:
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-paraformer-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -15,7 +15,7 @@ void OfflineParaformerModelConfig::Register(ParseOptions *po) {
bool
OfflineParaformerModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"Paraformer model
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"Paraformer model
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-transducer-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -18,19 +18,19 @@ void OfflineTransducerModelConfig::Register(ParseOptions *po) {
bool
OfflineTransducerModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
encoder_filename
))
{
SHERPA_ONNX_LOGE
(
"transducer encoder:
%s
does not exist"
,
SHERPA_ONNX_LOGE
(
"transducer encoder:
'%s'
does not exist"
,
encoder_filename
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
decoder_filename
))
{
SHERPA_ONNX_LOGE
(
"transducer decoder:
%s
does not exist"
,
SHERPA_ONNX_LOGE
(
"transducer decoder:
'%s'
does not exist"
,
decoder_filename
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
joiner_filename
))
{
SHERPA_ONNX_LOGE
(
"transducer joiner:
%s
does not exist"
,
SHERPA_ONNX_LOGE
(
"transducer joiner:
'%s'
does not exist"
,
joiner_filename
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-tts-vits-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -35,7 +35,7 @@ bool OfflineTtsVitsModelConfig::Validate() const {
}
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"--vits-model:
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"--vits-model:
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
@@ -45,31 +45,31 @@ bool OfflineTtsVitsModelConfig::Validate() const {
}
if
(
!
FileExists
(
tokens
))
{
SHERPA_ONNX_LOGE
(
"--vits-tokens:
%s
does not exist"
,
tokens
.
c_str
());
SHERPA_ONNX_LOGE
(
"--vits-tokens:
'%s'
does not exist"
,
tokens
.
c_str
());
return
false
;
}
if
(
!
data_dir
.
empty
())
{
if
(
!
FileExists
(
data_dir
+
"/phontab"
))
{
SHERPA_ONNX_LOGE
(
"
%s/phontab
does not exist. Skipping test"
,
SHERPA_ONNX_LOGE
(
"
'%s/phontab'
does not exist. Skipping test"
,
data_dir
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
data_dir
+
"/phonindex"
))
{
SHERPA_ONNX_LOGE
(
"
%s/phonindex
does not exist. Skipping test"
,
SHERPA_ONNX_LOGE
(
"
'%s/phonindex'
does not exist. Skipping test"
,
data_dir
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
data_dir
+
"/phondata"
))
{
SHERPA_ONNX_LOGE
(
"
%s/phondata
does not exist. Skipping test"
,
SHERPA_ONNX_LOGE
(
"
'%s/phondata'
does not exist. Skipping test"
,
data_dir
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
data_dir
+
"/intonations"
))
{
SHERPA_ONNX_LOGE
(
"
%s/intonations
does not exist."
,
data_dir
.
c_str
());
SHERPA_ONNX_LOGE
(
"
'%s/intonations'
does not exist."
,
data_dir
.
c_str
());
return
false
;
}
}
...
...
@@ -82,7 +82,8 @@ bool OfflineTtsVitsModelConfig::Validate() const {
for
(
const
auto
&
f
:
required_files
)
{
if
(
!
FileExists
(
dict_dir
+
"/"
+
f
))
{
SHERPA_ONNX_LOGE
(
"%s/%s does not exist."
,
data_dir
.
c_str
(),
f
.
c_str
());
SHERPA_ONNX_LOGE
(
"'%s/%s' does not exist."
,
data_dir
.
c_str
(),
f
.
c_str
());
return
false
;
}
}
...
...
sherpa-onnx/csrc/offline-tts.cc
查看文件 @
7f3b9ff
...
...
@@ -42,7 +42,7 @@ bool OfflineTtsConfig::Validate() const {
SplitStringToVector
(
rule_fsts
,
","
,
false
,
&
files
);
for
(
const
auto
&
f
:
files
)
{
if
(
!
FileExists
(
f
))
{
SHERPA_ONNX_LOGE
(
"Rule fst
%s
does not exist. "
,
f
.
c_str
());
SHERPA_ONNX_LOGE
(
"Rule fst
'%s'
does not exist. "
,
f
.
c_str
());
return
false
;
}
}
...
...
@@ -53,7 +53,7 @@ bool OfflineTtsConfig::Validate() const {
SplitStringToVector
(
rule_fars
,
","
,
false
,
&
files
);
for
(
const
auto
&
f
:
files
)
{
if
(
!
FileExists
(
f
))
{
SHERPA_ONNX_LOGE
(
"Rule far
%s
does not exist. "
,
f
.
c_str
());
SHERPA_ONNX_LOGE
(
"Rule far
'%s'
does not exist. "
,
f
.
c_str
());
return
false
;
}
}
...
...
sherpa-onnx/csrc/offline-wenet-ctc-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -18,7 +18,7 @@ void OfflineWenetCtcModelConfig::Register(ParseOptions *po) {
bool
OfflineWenetCtcModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"WeNet model:
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"WeNet model:
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-whisper-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -48,7 +48,8 @@ bool OfflineWhisperModelConfig::Validate() const {
}
if
(
!
FileExists
(
encoder
))
{
SHERPA_ONNX_LOGE
(
"whisper encoder file %s does not exist"
,
encoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"whisper encoder file '%s' does not exist"
,
encoder
.
c_str
());
return
false
;
}
...
...
@@ -58,7 +59,8 @@ bool OfflineWhisperModelConfig::Validate() const {
}
if
(
!
FileExists
(
decoder
))
{
SHERPA_ONNX_LOGE
(
"whisper decoder file %s does not exist"
,
decoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"whisper decoder file '%s' does not exist"
,
decoder
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-zipformer-audio-tagging-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -21,7 +21,7 @@ bool OfflineZipformerAudioTaggingModelConfig::Validate() const {
}
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"--zipformer-model:
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"--zipformer-model:
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/offline-zipformer-ctc-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -15,7 +15,7 @@ void OfflineZipformerCtcModelConfig::Register(ParseOptions *po) {
bool
OfflineZipformerCtcModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"zipformer CTC model file
%s
does not exist"
,
SHERPA_ONNX_LOGE
(
"zipformer CTC model file
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/online-ctc-fst-decoder-config.cc
查看文件 @
7f3b9ff
...
...
@@ -31,7 +31,7 @@ void OnlineCtcFstDecoderConfig::Register(ParseOptions *po) {
bool
OnlineCtcFstDecoderConfig
::
Validate
()
const
{
if
(
!
graph
.
empty
()
&&
!
FileExists
(
graph
))
{
SHERPA_ONNX_LOGE
(
"graph:
%s
does not exist"
,
graph
.
c_str
());
SHERPA_ONNX_LOGE
(
"graph:
'%s'
does not exist"
,
graph
.
c_str
());
return
false
;
}
return
true
;
...
...
sherpa-onnx/csrc/online-lm-config.cc
查看文件 @
7f3b9ff
...
...
@@ -22,7 +22,7 @@ void OnlineLMConfig::Register(ParseOptions *po) {
bool
OnlineLMConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/online-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -45,7 +45,7 @@ bool OnlineModelConfig::Validate() const {
}
if
(
!
FileExists
(
tokens
))
{
SHERPA_ONNX_LOGE
(
"tokens:
%s
does not exist"
,
tokens
.
c_str
());
SHERPA_ONNX_LOGE
(
"tokens:
'%s'
does not exist"
,
tokens
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/online-paraformer-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -18,12 +18,12 @@ void OnlineParaformerModelConfig::Register(ParseOptions *po) {
bool
OnlineParaformerModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
encoder
))
{
SHERPA_ONNX_LOGE
(
"Paraformer encoder
%s
does not exist"
,
encoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"Paraformer encoder
'%s'
does not exist"
,
encoder
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
decoder
))
{
SHERPA_ONNX_LOGE
(
"Paraformer decoder
%s
does not exist"
,
decoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"Paraformer decoder
'%s'
does not exist"
,
decoder
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/online-transducer-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -18,17 +18,19 @@ void OnlineTransducerModelConfig::Register(ParseOptions *po) {
bool
OnlineTransducerModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
encoder
))
{
SHERPA_ONNX_LOGE
(
"transducer encoder: %s does not exist"
,
encoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"transducer encoder: '%s' does not exist"
,
encoder
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
decoder
))
{
SHERPA_ONNX_LOGE
(
"transducer decoder: %s does not exist"
,
decoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"transducer decoder: '%s' does not exist"
,
decoder
.
c_str
());
return
false
;
}
if
(
!
FileExists
(
joiner
))
{
SHERPA_ONNX_LOGE
(
"joiner:
%s
does not exist"
,
joiner
.
c_str
());
SHERPA_ONNX_LOGE
(
"joiner:
'%s'
does not exist"
,
joiner
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/online-wenet-ctc-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -21,7 +21,7 @@ void OnlineWenetCtcModelConfig::Register(ParseOptions *po) {
bool
OnlineWenetCtcModelConfig
::
Validate
()
const
{
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"WeNet CTC model
%s
does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"WeNet CTC model
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/online-zipformer2-ctc-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -22,7 +22,8 @@ bool OnlineZipformer2CtcModelConfig::Validate() const {
}
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"--zipformer2-ctc-model %s does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"--zipformer2-ctc-model '%s' does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/silero-vad-model-config.cc
查看文件 @
7f3b9ff
...
...
@@ -44,7 +44,8 @@ bool SileroVadModelConfig::Validate() const {
}
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"Silero vad model file %s does not exist"
,
model
.
c_str
());
SHERPA_ONNX_LOGE
(
"Silero vad model file '%s' does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/speaker-embedding-extractor.cc
查看文件 @
7f3b9ff
...
...
@@ -31,7 +31,7 @@ bool SpeakerEmbeddingExtractorConfig::Validate() const {
}
if
(
!
FileExists
(
model
))
{
SHERPA_ONNX_LOGE
(
"--speaker-embedding-model:
%s
does not exist"
,
SHERPA_ONNX_LOGE
(
"--speaker-embedding-model:
'%s'
does not exist"
,
model
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/csrc/spoken-language-identification.cc
查看文件 @
7f3b9ff
...
...
@@ -43,7 +43,8 @@ bool SpokenLanguageIdentificationWhisperConfig::Validate() const {
}
if
(
!
FileExists
(
encoder
))
{
SHERPA_ONNX_LOGE
(
"whisper encoder file %s does not exist"
,
encoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"whisper encoder file '%s' does not exist"
,
encoder
.
c_str
());
return
false
;
}
...
...
@@ -53,7 +54,8 @@ bool SpokenLanguageIdentificationWhisperConfig::Validate() const {
}
if
(
!
FileExists
(
decoder
))
{
SHERPA_ONNX_LOGE
(
"whisper decoder file %s does not exist"
,
decoder
.
c_str
());
SHERPA_ONNX_LOGE
(
"whisper decoder file '%s' does not exist"
,
decoder
.
c_str
());
return
false
;
}
...
...
sherpa-onnx/jni/CMakeLists.txt
查看文件 @
7f3b9ff
...
...
@@ -9,11 +9,20 @@ if(NOT DEFINED ANDROID_ABI)
include_directories
(
$ENV{JAVA_HOME}/include/darwin
)
endif
()
add_library
(
sherpa-onnx-jni
set
(
sources
audio-tagging.cc
jni.cc
offline-stream.cc
spoken-language-identification.cc
)
if
(
SHERPA_ONNX_ENABLE_TTS
)
list
(
APPEND sources
offline-tts.cc
)
endif
()
add_library
(
sherpa-onnx-jni
${
sources
}
)
target_link_libraries
(
sherpa-onnx-jni sherpa-onnx-core
)
install
(
TARGETS sherpa-onnx-jni DESTINATION lib
)
...
...
sherpa-onnx/jni/jni.cc
查看文件 @
7f3b9ff
...
...
@@ -24,10 +24,6 @@
#include "sherpa-onnx/csrc/wave-writer.h"
#include "sherpa-onnx/jni/common.h"
#if SHERPA_ONNX_ENABLE_TTS == 1
#include "sherpa-onnx/csrc/offline-tts.h"
#endif
namespace
sherpa_onnx
{
class
SherpaOnnx
{
...
...
@@ -775,113 +771,6 @@ static VadModelConfig GetVadModelConfig(JNIEnv *env, jobject config) {
return
ans
;
}
#if SHERPA_ONNX_ENABLE_TTS == 1
class
SherpaOnnxOfflineTts
{
public
:
#if __ANDROID_API__ >= 9
SherpaOnnxOfflineTts
(
AAssetManager
*
mgr
,
const
OfflineTtsConfig
&
config
)
:
tts_
(
mgr
,
config
)
{}
#endif
explicit
SherpaOnnxOfflineTts
(
const
OfflineTtsConfig
&
config
)
:
tts_
(
config
)
{}
GeneratedAudio
Generate
(
const
std
::
string
&
text
,
int64_t
sid
=
0
,
float
speed
=
1.0
,
std
::
function
<
void
(
const
float
*
,
int32_t
,
float
)
>
callback
=
nullptr
)
const
{
return
tts_
.
Generate
(
text
,
sid
,
speed
,
callback
);
}
int32_t
SampleRate
()
const
{
return
tts_
.
SampleRate
();
}
int32_t
NumSpeakers
()
const
{
return
tts_
.
NumSpeakers
();
}
private
:
OfflineTts
tts_
;
};
static
OfflineTtsConfig
GetOfflineTtsConfig
(
JNIEnv
*
env
,
jobject
config
)
{
OfflineTtsConfig
ans
;
jclass
cls
=
env
->
GetObjectClass
(
config
);
jfieldID
fid
;
fid
=
env
->
GetFieldID
(
cls
,
"model"
,
"Lcom/k2fsa/sherpa/onnx/OfflineTtsModelConfig;"
);
jobject
model
=
env
->
GetObjectField
(
config
,
fid
);
jclass
model_config_cls
=
env
->
GetObjectClass
(
model
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"vits"
,
"Lcom/k2fsa/sherpa/onnx/OfflineTtsVitsModelConfig;"
);
jobject
vits
=
env
->
GetObjectField
(
model
,
fid
);
jclass
vits_cls
=
env
->
GetObjectClass
(
vits
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"model"
,
"Ljava/lang/String;"
);
jstring
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
const
char
*
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
model
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"lexicon"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
lexicon
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"tokens"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
tokens
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"dataDir"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
data_dir
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"noiseScale"
,
"F"
);
ans
.
model
.
vits
.
noise_scale
=
env
->
GetFloatField
(
vits
,
fid
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"noiseScaleW"
,
"F"
);
ans
.
model
.
vits
.
noise_scale_w
=
env
->
GetFloatField
(
vits
,
fid
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"lengthScale"
,
"F"
);
ans
.
model
.
vits
.
length_scale
=
env
->
GetFloatField
(
vits
,
fid
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"numThreads"
,
"I"
);
ans
.
model
.
num_threads
=
env
->
GetIntField
(
model
,
fid
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"debug"
,
"Z"
);
ans
.
model
.
debug
=
env
->
GetBooleanField
(
model
,
fid
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"provider"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
model
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
provider
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
// for ruleFsts
fid
=
env
->
GetFieldID
(
cls
,
"ruleFsts"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
config
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
rule_fsts
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
// for ruleFars
fid
=
env
->
GetFieldID
(
cls
,
"ruleFars"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
config
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
rule_fars
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
cls
,
"maxNumSentences"
,
"I"
);
ans
.
max_num_sentences
=
env
->
GetIntField
(
config
,
fid
);
return
ans
;
}
#endif
}
// namespace sherpa_onnx
SHERPA_ONNX_EXTERN_C
...
...
@@ -1226,128 +1115,6 @@ jobject NewFloat(JNIEnv *env, float value) {
return
env
->
NewObject
(
cls
,
constructor
,
value
);
}
#if SHERPA_ONNX_ENABLE_TTS == 1
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jlong
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_new
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jobject
asset_manager
,
jobject
_config
)
{
#if __ANDROID_API__ >= 9
AAssetManager
*
mgr
=
AAssetManager_fromJava
(
env
,
asset_manager
);
if
(
!
mgr
)
{
SHERPA_ONNX_LOGE
(
"Failed to get asset manager: %p"
,
mgr
);
}
#endif
auto
config
=
sherpa_onnx
::
GetOfflineTtsConfig
(
env
,
_config
);
SHERPA_ONNX_LOGE
(
"config:
\n
%s"
,
config
.
ToString
().
c_str
());
auto
tts
=
new
sherpa_onnx
::
SherpaOnnxOfflineTts
(
#if __ANDROID_API__ >= 9
mgr
,
#endif
config
);
return
(
jlong
)
tts
;
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jlong
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_newFromFile
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jobject
_config
)
{
auto
config
=
sherpa_onnx
::
GetOfflineTtsConfig
(
env
,
_config
);
SHERPA_ONNX_LOGE
(
"config:
\n
%s"
,
config
.
ToString
().
c_str
());
if
(
!
config
.
Validate
())
{
SHERPA_ONNX_LOGE
(
"Errors found in config!"
);
}
auto
tts
=
new
sherpa_onnx
::
SherpaOnnxOfflineTts
(
config
);
return
(
jlong
)
tts
;
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
void
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_delete
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
)
{
delete
reinterpret_cast
<
sherpa_onnx
::
SherpaOnnxOfflineTts
*>
(
ptr
);
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jint
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_getSampleRate
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
)
{
return
reinterpret_cast
<
sherpa_onnx
::
SherpaOnnxOfflineTts
*>
(
ptr
)
->
SampleRate
();
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jint
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_getNumSpeakers
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
)
{
return
reinterpret_cast
<
sherpa_onnx
::
SherpaOnnxOfflineTts
*>
(
ptr
)
->
NumSpeakers
();
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jobjectArray
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_generateImpl
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
,
jstring
text
,
jint
sid
,
jfloat
speed
)
{
const
char
*
p_text
=
env
->
GetStringUTFChars
(
text
,
nullptr
);
SHERPA_ONNX_LOGE
(
"string is: %s"
,
p_text
);
auto
audio
=
reinterpret_cast
<
sherpa_onnx
::
SherpaOnnxOfflineTts
*>
(
ptr
)
->
Generate
(
p_text
,
sid
,
speed
);
jfloatArray
samples_arr
=
env
->
NewFloatArray
(
audio
.
samples
.
size
());
env
->
SetFloatArrayRegion
(
samples_arr
,
0
,
audio
.
samples
.
size
(),
audio
.
samples
.
data
());
jobjectArray
obj_arr
=
(
jobjectArray
)
env
->
NewObjectArray
(
2
,
env
->
FindClass
(
"java/lang/Object"
),
nullptr
);
env
->
SetObjectArrayElement
(
obj_arr
,
0
,
samples_arr
);
env
->
SetObjectArrayElement
(
obj_arr
,
1
,
NewInteger
(
env
,
audio
.
sample_rate
));
env
->
ReleaseStringUTFChars
(
text
,
p_text
);
return
obj_arr
;
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jobjectArray
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_generateWithCallbackImpl
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
,
jstring
text
,
jint
sid
,
jfloat
speed
,
jobject
callback
)
{
const
char
*
p_text
=
env
->
GetStringUTFChars
(
text
,
nullptr
);
SHERPA_ONNX_LOGE
(
"string is: %s"
,
p_text
);
std
::
function
<
void
(
const
float
*
,
int32_t
,
float
)
>
callback_wrapper
=
[
env
,
callback
](
const
float
*
samples
,
int32_t
n
,
float
/*p*/
)
{
jclass
cls
=
env
->
GetObjectClass
(
callback
);
jmethodID
mid
=
env
->
GetMethodID
(
cls
,
"invoke"
,
"([F)V"
);
jfloatArray
samples_arr
=
env
->
NewFloatArray
(
n
);
env
->
SetFloatArrayRegion
(
samples_arr
,
0
,
n
,
samples
);
env
->
CallVoidMethod
(
callback
,
mid
,
samples_arr
);
};
auto
audio
=
reinterpret_cast
<
sherpa_onnx
::
SherpaOnnxOfflineTts
*>
(
ptr
)
->
Generate
(
p_text
,
sid
,
speed
,
callback_wrapper
);
jfloatArray
samples_arr
=
env
->
NewFloatArray
(
audio
.
samples
.
size
());
env
->
SetFloatArrayRegion
(
samples_arr
,
0
,
audio
.
samples
.
size
(),
audio
.
samples
.
data
());
jobjectArray
obj_arr
=
(
jobjectArray
)
env
->
NewObjectArray
(
2
,
env
->
FindClass
(
"java/lang/Object"
),
nullptr
);
env
->
SetObjectArrayElement
(
obj_arr
,
0
,
samples_arr
);
env
->
SetObjectArrayElement
(
obj_arr
,
1
,
NewInteger
(
env
,
audio
.
sample_rate
));
env
->
ReleaseStringUTFChars
(
text
,
p_text
);
return
obj_arr
;
}
#endif
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jboolean
JNICALL
Java_com_k2fsa_sherpa_onnx_GeneratedAudio_saveImpl
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jstring
filename
,
jfloatArray
samples
,
...
...
sherpa-onnx/jni/offline-tts.cc
0 → 100644
查看文件 @
7f3b9ff
// sherpa-onnx/jni/offline-tts.cc
//
// Copyright (c) 2024 Xiaomi Corporation
#include "sherpa-onnx/csrc/offline-tts.h"
#include "sherpa-onnx/csrc/macros.h"
#include "sherpa-onnx/jni/common.h"
namespace
sherpa_onnx
{
static
OfflineTtsConfig
GetOfflineTtsConfig
(
JNIEnv
*
env
,
jobject
config
)
{
OfflineTtsConfig
ans
;
jclass
cls
=
env
->
GetObjectClass
(
config
);
jfieldID
fid
;
fid
=
env
->
GetFieldID
(
cls
,
"model"
,
"Lcom/k2fsa/sherpa/onnx/OfflineTtsModelConfig;"
);
jobject
model
=
env
->
GetObjectField
(
config
,
fid
);
jclass
model_config_cls
=
env
->
GetObjectClass
(
model
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"vits"
,
"Lcom/k2fsa/sherpa/onnx/OfflineTtsVitsModelConfig;"
);
jobject
vits
=
env
->
GetObjectField
(
model
,
fid
);
jclass
vits_cls
=
env
->
GetObjectClass
(
vits
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"model"
,
"Ljava/lang/String;"
);
jstring
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
const
char
*
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
model
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"lexicon"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
lexicon
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"tokens"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
tokens
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"dataDir"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
data_dir
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"dictDir"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
vits
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
vits
.
dict_dir
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"noiseScale"
,
"F"
);
ans
.
model
.
vits
.
noise_scale
=
env
->
GetFloatField
(
vits
,
fid
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"noiseScaleW"
,
"F"
);
ans
.
model
.
vits
.
noise_scale_w
=
env
->
GetFloatField
(
vits
,
fid
);
fid
=
env
->
GetFieldID
(
vits_cls
,
"lengthScale"
,
"F"
);
ans
.
model
.
vits
.
length_scale
=
env
->
GetFloatField
(
vits
,
fid
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"numThreads"
,
"I"
);
ans
.
model
.
num_threads
=
env
->
GetIntField
(
model
,
fid
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"debug"
,
"Z"
);
ans
.
model
.
debug
=
env
->
GetBooleanField
(
model
,
fid
);
fid
=
env
->
GetFieldID
(
model_config_cls
,
"provider"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
model
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
model
.
provider
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
// for ruleFsts
fid
=
env
->
GetFieldID
(
cls
,
"ruleFsts"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
config
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
rule_fsts
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
// for ruleFars
fid
=
env
->
GetFieldID
(
cls
,
"ruleFars"
,
"Ljava/lang/String;"
);
s
=
(
jstring
)
env
->
GetObjectField
(
config
,
fid
);
p
=
env
->
GetStringUTFChars
(
s
,
nullptr
);
ans
.
rule_fars
=
p
;
env
->
ReleaseStringUTFChars
(
s
,
p
);
fid
=
env
->
GetFieldID
(
cls
,
"maxNumSentences"
,
"I"
);
ans
.
max_num_sentences
=
env
->
GetIntField
(
config
,
fid
);
return
ans
;
}
}
// namespace sherpa_onnx
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jlong
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_newForAsset
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jobject
asset_manager
,
jobject
_config
)
{
#if __ANDROID_API__ >= 9
AAssetManager
*
mgr
=
AAssetManager_fromJava
(
env
,
asset_manager
);
if
(
!
mgr
)
{
SHERPA_ONNX_LOGE
(
"Failed to get asset manager: %p"
,
mgr
);
}
#endif
auto
config
=
sherpa_onnx
::
GetOfflineTtsConfig
(
env
,
_config
);
SHERPA_ONNX_LOGE
(
"config:
\n
%s"
,
config
.
ToString
().
c_str
());
auto
tts
=
new
sherpa_onnx
::
OfflineTts
(
#if __ANDROID_API__ >= 9
mgr
,
#endif
config
);
return
(
jlong
)
tts
;
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jlong
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_newFromFile
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jobject
_config
)
{
auto
config
=
sherpa_onnx
::
GetOfflineTtsConfig
(
env
,
_config
);
SHERPA_ONNX_LOGE
(
"config:
\n
%s"
,
config
.
ToString
().
c_str
());
if
(
!
config
.
Validate
())
{
SHERPA_ONNX_LOGE
(
"Errors found in config!"
);
}
auto
tts
=
new
sherpa_onnx
::
OfflineTts
(
config
);
return
(
jlong
)
tts
;
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
void
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_delete
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
)
{
delete
reinterpret_cast
<
sherpa_onnx
::
OfflineTts
*>
(
ptr
);
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jint
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_getSampleRate
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
)
{
return
reinterpret_cast
<
sherpa_onnx
::
OfflineTts
*>
(
ptr
)
->
SampleRate
();
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jint
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_getNumSpeakers
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
)
{
return
reinterpret_cast
<
sherpa_onnx
::
OfflineTts
*>
(
ptr
)
->
NumSpeakers
();
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jobjectArray
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_generateImpl
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
,
jstring
text
,
jint
sid
,
jfloat
speed
)
{
const
char
*
p_text
=
env
->
GetStringUTFChars
(
text
,
nullptr
);
SHERPA_ONNX_LOGE
(
"string is: %s"
,
p_text
);
auto
audio
=
reinterpret_cast
<
sherpa_onnx
::
OfflineTts
*>
(
ptr
)
->
Generate
(
p_text
,
sid
,
speed
);
jfloatArray
samples_arr
=
env
->
NewFloatArray
(
audio
.
samples
.
size
());
env
->
SetFloatArrayRegion
(
samples_arr
,
0
,
audio
.
samples
.
size
(),
audio
.
samples
.
data
());
jobjectArray
obj_arr
=
(
jobjectArray
)
env
->
NewObjectArray
(
2
,
env
->
FindClass
(
"java/lang/Object"
),
nullptr
);
env
->
SetObjectArrayElement
(
obj_arr
,
0
,
samples_arr
);
env
->
SetObjectArrayElement
(
obj_arr
,
1
,
NewInteger
(
env
,
audio
.
sample_rate
));
env
->
ReleaseStringUTFChars
(
text
,
p_text
);
return
obj_arr
;
}
SHERPA_ONNX_EXTERN_C
JNIEXPORT
jobjectArray
JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineTts_generateWithCallbackImpl
(
JNIEnv
*
env
,
jobject
/*obj*/
,
jlong
ptr
,
jstring
text
,
jint
sid
,
jfloat
speed
,
jobject
callback
)
{
const
char
*
p_text
=
env
->
GetStringUTFChars
(
text
,
nullptr
);
SHERPA_ONNX_LOGE
(
"string is: %s"
,
p_text
);
std
::
function
<
void
(
const
float
*
,
int32_t
,
float
)
>
callback_wrapper
=
[
env
,
callback
](
const
float
*
samples
,
int32_t
n
,
float
/*progress*/
)
{
jclass
cls
=
env
->
GetObjectClass
(
callback
);
jmethodID
mid
=
env
->
GetMethodID
(
cls
,
"invoke"
,
"([F)V"
);
jfloatArray
samples_arr
=
env
->
NewFloatArray
(
n
);
env
->
SetFloatArrayRegion
(
samples_arr
,
0
,
n
,
samples
);
env
->
CallVoidMethod
(
callback
,
mid
,
samples_arr
);
};
auto
audio
=
reinterpret_cast
<
sherpa_onnx
::
OfflineTts
*>
(
ptr
)
->
Generate
(
p_text
,
sid
,
speed
,
callback_wrapper
);
jfloatArray
samples_arr
=
env
->
NewFloatArray
(
audio
.
samples
.
size
());
env
->
SetFloatArrayRegion
(
samples_arr
,
0
,
audio
.
samples
.
size
(),
audio
.
samples
.
data
());
jobjectArray
obj_arr
=
(
jobjectArray
)
env
->
NewObjectArray
(
2
,
env
->
FindClass
(
"java/lang/Object"
),
nullptr
);
env
->
SetObjectArrayElement
(
obj_arr
,
0
,
samples_arr
);
env
->
SetObjectArrayElement
(
obj_arr
,
1
,
NewInteger
(
env
,
audio
.
sample_rate
));
env
->
ReleaseStringUTFChars
(
text
,
p_text
);
return
obj_arr
;
}
...
...
请
注册
或
登录
后发表评论