Add jni interface and kotlin API examples for TTS. (#381)
This commit is contained in:
3
kotlin-api-examples/.gitignore
vendored
Normal file
3
kotlin-api-examples/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
hs_err*
|
||||
main.jar
|
||||
vits-zh-aishell3
|
||||
@@ -3,6 +3,28 @@ package com.k2fsa.sherpa.onnx
|
||||
import android.content.res.AssetManager
|
||||
|
||||
fun main() {
|
||||
testTts()
|
||||
testAsr()
|
||||
}
|
||||
|
||||
fun testTts() {
|
||||
var config = OfflineTtsConfig(
|
||||
model=OfflineTtsModelConfig(
|
||||
vits=OfflineTtsVitsModelConfig(
|
||||
model="./vits-zh-aishell3/vits-aishell3.onnx",
|
||||
lexicon="./vits-zh-aishell3/lexicon.txt",
|
||||
tokens="./vits-zh-aishell3/tokens.txt",
|
||||
),
|
||||
numThreads=1,
|
||||
debug=true,
|
||||
)
|
||||
)
|
||||
val tts = OfflineTts(config=config)
|
||||
val audio = tts.generate(text="林美丽最美丽!", sid=99, speed=1.2f)
|
||||
audio.save(filename="99.wav")
|
||||
}
|
||||
|
||||
fun testAsr() {
|
||||
var featConfig = FeatureConfig(
|
||||
sampleRate = 16000,
|
||||
featureDim = 80,
|
||||
|
||||
112
kotlin-api-examples/Tts.kt
Normal file
112
kotlin-api-examples/Tts.kt
Normal file
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) 2023 Xiaomi Corporation
|
||||
package com.k2fsa.sherpa.onnx
|
||||
|
||||
import android.content.res.AssetManager
|
||||
|
||||
data class OfflineTtsVitsModelConfig(
|
||||
var model: String,
|
||||
var lexicon: String,
|
||||
var tokens: String,
|
||||
var noiseScale: Float = 0.667f,
|
||||
var noiseScaleW: Float = 0.8f,
|
||||
var lengthScale: Float = 1.0f,
|
||||
)
|
||||
|
||||
data class OfflineTtsModelConfig(
|
||||
var vits: OfflineTtsVitsModelConfig,
|
||||
var numThreads: Int = 1,
|
||||
var debug: Boolean = false,
|
||||
var provider: String = "cpu",
|
||||
)
|
||||
|
||||
data class OfflineTtsConfig(
|
||||
var model: OfflineTtsModelConfig,
|
||||
)
|
||||
|
||||
class GeneratedAudio(
|
||||
val samples : FloatArray,
|
||||
val sampleRate: Int,
|
||||
) {
|
||||
fun save(filename: String) = saveImpl(filename=filename, samples=samples, sampleRate=sampleRate)
|
||||
|
||||
private external fun saveImpl(
|
||||
filename: String,
|
||||
samples: FloatArray,
|
||||
sampleRate: Int
|
||||
): Boolean
|
||||
}
|
||||
|
||||
class OfflineTts(
|
||||
assetManager: AssetManager? = null,
|
||||
var config: OfflineTtsConfig,
|
||||
) {
|
||||
private var ptr: Long
|
||||
|
||||
init {
|
||||
if (assetManager != null) {
|
||||
ptr = new(assetManager, config)
|
||||
} else {
|
||||
ptr = newFromFile(config)
|
||||
}
|
||||
}
|
||||
|
||||
fun generate(
|
||||
text: String,
|
||||
sid: Int = 0,
|
||||
speed: Float = 1.0f
|
||||
): GeneratedAudio {
|
||||
var objArray = generateImpl(ptr, text=text, sid=sid, speed=speed)
|
||||
return GeneratedAudio(samples=objArray[0] as FloatArray,
|
||||
sampleRate=objArray[1] as Int)
|
||||
}
|
||||
|
||||
fun allocate(assetManager: AssetManager? = null) {
|
||||
if (ptr == 0L) {
|
||||
if (assetManager != null) {
|
||||
ptr = new(assetManager, config)
|
||||
} else {
|
||||
ptr = newFromFile(config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun free() {
|
||||
if (ptr != 0L) {
|
||||
delete(ptr)
|
||||
ptr = 0
|
||||
}
|
||||
}
|
||||
|
||||
protected fun finalize() {
|
||||
delete(ptr)
|
||||
}
|
||||
|
||||
private external fun new(
|
||||
assetManager: AssetManager,
|
||||
config: OfflineTtsConfig,
|
||||
): Long
|
||||
|
||||
private external fun newFromFile(
|
||||
config: OfflineTtsConfig,
|
||||
): Long
|
||||
|
||||
private external fun delete(ptr: Long)
|
||||
|
||||
// The returned array has two entries:
|
||||
// - the first entry is an 1-D float array containing audio samples.
|
||||
// Each sample is normalized to the range [-1, 1]
|
||||
// - the second entry is the sample rate
|
||||
external fun generateImpl(
|
||||
ptr: Long,
|
||||
text: String,
|
||||
sid: Int = 0,
|
||||
speed: Float = 1.0f
|
||||
): Array<Any>
|
||||
|
||||
companion object {
|
||||
init {
|
||||
System.loadLibrary("sherpa-onnx-jni")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,21 +6,24 @@
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
cd ..
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
cmake \
|
||||
-DSHERPA_ONNX_ENABLE_PYTHON=OFF \
|
||||
-DSHERPA_ONNX_ENABLE_TESTS=OFF \
|
||||
-DSHERPA_ONNX_ENABLE_CHECK=OFF \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
|
||||
-DSHERPA_ONNX_ENABLE_JNI=ON \
|
||||
..
|
||||
if [ ! -f ../build/lib/libsherpa-onnx-jni.dylib ]; then
|
||||
cmake \
|
||||
-DSHERPA_ONNX_ENABLE_PYTHON=OFF \
|
||||
-DSHERPA_ONNX_ENABLE_TESTS=OFF \
|
||||
-DSHERPA_ONNX_ENABLE_CHECK=OFF \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
|
||||
-DSHERPA_ONNX_ENABLE_JNI=ON \
|
||||
..
|
||||
|
||||
make -j4
|
||||
ls -lh lib
|
||||
make -j4
|
||||
ls -lh lib
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH=$PWD/build/lib:$LD_LIBRARY_PATH
|
||||
|
||||
@@ -31,7 +34,7 @@ if [ ! -f ./sherpa-onnx-streaming-zipformer-en-2023-02-21/tokens.txt ]; then
|
||||
git clone https://huggingface.co/csukuangfj/sherpa-onnx-streaming-zipformer-en-2023-02-21
|
||||
fi
|
||||
|
||||
kotlinc-jvm -include-runtime -d main.jar Main.kt WaveReader.kt SherpaOnnx.kt faked-asset-manager.kt
|
||||
kotlinc-jvm -include-runtime -d main.jar Main.kt WaveReader.kt SherpaOnnx.kt faked-asset-manager.kt Tts.kt
|
||||
|
||||
ls -lh main.jar
|
||||
|
||||
|
||||
Reference in New Issue
Block a user