正在显示
90 个修改的文件
包含
1645 行增加
和
766 行删除
sherpa-onnx/java-api/.build.txt
0 → 100644
| 1 | +[win.env] | ||
| 2 | +set JAVA_HOME=D:\java\jdk1.8.0_121 | ||
| 3 | + | ||
| 4 | +[win.build] | ||
| 5 | +mvn clean install -DskipTests -Dgpg.skip=true | ||
| 6 | + | ||
| 7 | +[linux.env] | ||
| 8 | +export JAVA_HOME=/usr/java/jdk1.8.0_121 | ||
| 9 | + | ||
| 10 | +[linux.build] | ||
| 11 | +mvn clean install -DskipTests -Dgpg.skip=true | ||
| 12 | + | ||
| 13 | +[mac.env] | ||
| 14 | +export JAVA_HOME=~/java/jdk1.8.0_121 | ||
| 15 | + | ||
| 16 | +[mac.build] | ||
| 17 | +mvn clean install -DskipTests -Dgpg.skip=true |
| 1 | -.idea | ||
| 2 | -java-api.iml | ||
| 3 | -out | ||
| 4 | -META-INF | ||
| 5 | -build | ||
| 6 | -*.jar | 1 | +### Eclipse template |
| 2 | +*.pydevproject | ||
| 3 | +.metadata | ||
| 4 | +.gradle* | ||
| 5 | +classes/ | ||
| 6 | +bin/ | ||
| 7 | +tmp/ | ||
| 8 | +*.tmp | ||
| 9 | +*.bak | ||
| 10 | +*.swp | ||
| 11 | +*~.nib | ||
| 12 | +local.properties | ||
| 13 | +.settings/ | ||
| 14 | +.loadpath | ||
| 15 | +rebel.xml | ||
| 16 | + | ||
| 17 | +# Eclipse Core | ||
| 18 | +.project | ||
| 19 | + | ||
| 20 | +generatedsources | ||
| 21 | + | ||
| 22 | +# External tool builders | ||
| 23 | +.externalToolBuilders/ | ||
| 24 | + | ||
| 25 | +# Locally stored "Eclipse launch configurations" | ||
| 26 | +*.launch | ||
| 27 | + | ||
| 28 | +# CDT-specific | ||
| 29 | +.cproject | ||
| 30 | + | ||
| 31 | +# JDT-specific (Eclipse Java Development Tools) | ||
| 32 | +.classpath | ||
| 33 | + | ||
| 34 | +# PDT-specific | ||
| 35 | +.buildpath | ||
| 36 | + | ||
| 37 | +# sbteclipse plugin | ||
| 38 | +.target | ||
| 39 | + | ||
| 40 | +# TeXlipse plugin | ||
| 41 | +.texlipse | ||
| 42 | + | ||
| 43 | + | ||
| 44 | + | ||
| 45 | +### JetBrains template | ||
| 46 | +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm | ||
| 47 | + | ||
| 48 | +*.iml | ||
| 49 | +.flattened-pom.xml | ||
| 50 | +## Directory-based project format: | ||
| 51 | +.idea/ | ||
| 52 | +# if you remove the above rule, at least ignore the following: | ||
| 53 | + | ||
| 54 | +# User-specific stuff: | ||
| 55 | +# .idea/workspace.xml | ||
| 56 | +# .idea/tasks.xml | ||
| 57 | +# .idea/dictionaries | ||
| 58 | + | ||
| 59 | +# Sensitive or high-churn files: | ||
| 60 | +# .idea/dataSources.ids | ||
| 61 | +# .idea/dataSources.xml | ||
| 62 | +# .idea/sqlDataSources.xml | ||
| 63 | +# .idea/dynamic.xml | ||
| 64 | +# .idea/uiDesigner.xml | ||
| 65 | + | ||
| 66 | +# Gradle: | ||
| 67 | +# .idea/gradle.xml | ||
| 68 | +# .idea/libraries | ||
| 69 | + | ||
| 70 | +# Mongo Explorer plugin: | ||
| 71 | +# .idea/mongoSettings.xml | ||
| 72 | + | ||
| 73 | +## File-based project format: | ||
| 74 | +*.ipr | ||
| 75 | +*.iws | ||
| 76 | + | ||
| 77 | +## Plugin-specific files: | ||
| 78 | + | ||
| 79 | +# IntelliJ | ||
| 80 | +/out/ | ||
| 81 | + | ||
| 82 | +# mpeltonen/sbt-idea plugin | ||
| 83 | +.idea_modules/ | ||
| 84 | + | ||
| 85 | +# JIRA plugin | ||
| 86 | +atlassian-ide-plugin.xml | ||
| 87 | + | ||
| 88 | +# Crashlytics plugin (for Android Studio and IntelliJ) | ||
| 89 | +com_crashlytics_export_strings.xml | ||
| 90 | +crashlytics.properties | ||
| 91 | +crashlytics-build.properties | ||
| 92 | + | ||
| 93 | +build/ | ||
| 94 | + | ||
| 95 | +# Ignore Gradle GUI config | ||
| 96 | +gradle-app.setting | ||
| 97 | + | ||
| 98 | +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) | ||
| 99 | +!gradle-wrapper.jar | ||
| 100 | + | ||
| 101 | +db | ||
| 102 | + | ||
| 103 | +### Java template | ||
| 104 | +*.class | ||
| 105 | + | ||
| 106 | +# Mobile Tools for Java (J2ME) | ||
| 107 | +.mtj.tmp/ | ||
| 108 | + | ||
| 109 | +# Package Files # | ||
| 110 | +#*.jar | ||
| 111 | + | ||
| 112 | +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | ||
| 113 | +hs_err_pid* | ||
| 114 | + | ||
| 115 | + | ||
| 116 | +### Leiningen template | ||
| 117 | +classes/ | ||
| 118 | +target/ | ||
| 119 | +logs/ | ||
| 120 | +checkouts/ | ||
| 121 | +.lein-deps-sum | ||
| 122 | +.lein-repl-history | ||
| 123 | +.lein-plugins/ | ||
| 124 | +.lein-failures | ||
| 125 | +.nrepl-port | ||
| 126 | + | ||
| 127 | +querydsl/ | ||
| 128 | + | ||
| 129 | +.DS_Store | ||
| 130 | + | ||
| 131 | +*.exe | ||
| 132 | +*.out | ||
| 133 | + | ||
| 134 | +*.log | ||
| 135 | +node_modules/ | ||
| 136 | +dist/ | ||
| 137 | +dist.zip | ||
| 138 | +package-lock.json | ||
| 139 | +*.lock | ||
| 140 | +local.properties | ||
| 141 | +.cxx | ||
| 142 | +.externalNativeBuild | ||
| 143 | +/captures | ||
| 144 | +/build | ||
| 145 | +__pycache__/ | ||
| 146 | +*.pyc | ||
| 147 | + | ||
| 148 | + | ||
| 149 | +cmake-build-debug/ | ||
| 150 | +cmake-build-debug-mingw/ | ||
| 151 | +venv/ | ||
| 152 | +.vs/ | ||
| 153 | +Debug/ | ||
| 154 | +vcpkg_installed/ | ||
| 155 | +.env | ||
| 156 | +.next/ | ||
| 157 | +app.zip | ||
| 158 | +secrets.txt | ||
| 159 | +src.zip |
| @@ -101,7 +101,7 @@ java_files += OfflineSpeechDenoiser.java | @@ -101,7 +101,7 @@ java_files += OfflineSpeechDenoiser.java | ||
| 101 | 101 | ||
| 102 | class_files := $(java_files:%.java=%.class) | 102 | class_files := $(java_files:%.java=%.class) |
| 103 | 103 | ||
| 104 | -java_files := $(addprefix src/$(package_dir)/,$(java_files)) | 104 | +java_files := $(addprefix src/main/java/$(package_dir)/,$(java_files)) |
| 105 | class_files := $(addprefix $(out_dir)/$(package_dir)/,$(class_files)) | 105 | class_files := $(addprefix $(out_dir)/$(package_dir)/,$(class_files)) |
| 106 | 106 | ||
| 107 | $(info -- java files $(java_files)) | 107 | $(info -- java files $(java_files)) |
| @@ -119,6 +119,6 @@ $(out_jar): $(class_files) | @@ -119,6 +119,6 @@ $(out_jar): $(class_files) | ||
| 119 | clean: | 119 | clean: |
| 120 | $(RM) -rfv $(out_dir) | 120 | $(RM) -rfv $(out_dir) |
| 121 | 121 | ||
| 122 | -$(class_files): $(out_dir)/$(package_dir)/%.class: src/$(package_dir)/%.java | 122 | +$(class_files): $(out_dir)/$(package_dir)/%.class: src/main/java/$(package_dir)/%.java |
| 123 | mkdir -p build | 123 | mkdir -p build |
| 124 | javac -d $(out_dir) -cp $(out_dir) $< | 124 | javac -d $(out_dir) -cp $(out_dir) $< |
sherpa-onnx/java-api/pom.xml
0 → 100644
| 1 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 2 | + <modelVersion>4.0.0</modelVersion> | ||
| 3 | + <groupId>com.litongjava</groupId> | ||
| 4 | + <artifactId>sherpa-onnx-java-api</artifactId> | ||
| 5 | + <version>1.0.1</version> | ||
| 6 | + <packaging>jar</packaging> | ||
| 7 | + <name>sherpa-onnx-java-api</name> | ||
| 8 | + <description>sherpa-onnx-java-api</description> | ||
| 9 | + <url>https://github.com/k2-fsa/sherpa-onnx/tree/master/sherpa-onnx/java-api</url> | ||
| 10 | + <properties> | ||
| 11 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| 12 | + <java.version>1.8</java.version> | ||
| 13 | + <maven.compiler.source>${java.version}</maven.compiler.source> | ||
| 14 | + <maven.compiler.target>${java.version}</maven.compiler.target> | ||
| 15 | + </properties> | ||
| 16 | + | ||
| 17 | + <licenses> | ||
| 18 | + <license> | ||
| 19 | + <name>The Apache Software License, Version 2.0</name> | ||
| 20 | + <url>http://apache.org/licenses/LICENSE-2.0.txt</url> | ||
| 21 | + </license> | ||
| 22 | + </licenses> | ||
| 23 | + | ||
| 24 | + <developers> | ||
| 25 | + <developer> | ||
| 26 | + <id>litongjava</id> | ||
| 27 | + <name>Tong Li</name> | ||
| 28 | + <email>litongjava001@gmail.com</email> | ||
| 29 | + <url>https://github.com/litongjava</url> | ||
| 30 | + </developer> | ||
| 31 | + </developers> | ||
| 32 | + | ||
| 33 | + <scm> | ||
| 34 | + <connection>scm:git:git@github.com:k2-fsa/sherpa-onnx.git</connection> | ||
| 35 | + <developerConnection>scm:git:git@github.com:k2-fsa/sherpa-onnx.git</developerConnection> | ||
| 36 | + <url>git@github.com:k2-fsa/sherpa-onnx.git</url> | ||
| 37 | + </scm> | ||
| 38 | + | ||
| 39 | + <build> | ||
| 40 | + <plugins> | ||
| 41 | + <!-- Source --> | ||
| 42 | + <plugin> | ||
| 43 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 44 | + <artifactId>maven-source-plugin</artifactId> | ||
| 45 | + <version>2.2.1</version> | ||
| 46 | + <executions> | ||
| 47 | + <execution> | ||
| 48 | + <phase>package</phase> | ||
| 49 | + <goals> | ||
| 50 | + <goal>jar-no-fork</goal> | ||
| 51 | + </goals> | ||
| 52 | + </execution> | ||
| 53 | + </executions> | ||
| 54 | + </plugin> | ||
| 55 | + <!-- Javadoc --> | ||
| 56 | + <plugin> | ||
| 57 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 58 | + <artifactId>maven-javadoc-plugin</artifactId> | ||
| 59 | + <version>2.9.1</version> | ||
| 60 | + <configuration> | ||
| 61 | + <!-- 添加这个压制JavaDoc检查 --> | ||
| 62 | + <additionalparam>-Xdoclint:none</additionalparam> | ||
| 63 | + </configuration> | ||
| 64 | + <executions> | ||
| 65 | + <execution> | ||
| 66 | + <phase>package</phase> | ||
| 67 | + <goals> | ||
| 68 | + <goal>jar</goal> | ||
| 69 | + </goals> | ||
| 70 | + </execution> | ||
| 71 | + </executions> | ||
| 72 | + </plugin> | ||
| 73 | + <!-- GPG mvn clean deploy -Dgpg.passphrase=YourPassphase --> | ||
| 74 | + <plugin> | ||
| 75 | + <groupId>org.apache.maven.plugins</groupId> | ||
| 76 | + <artifactId>maven-gpg-plugin</artifactId> | ||
| 77 | + <version>1.5</version> | ||
| 78 | + <executions> | ||
| 79 | + <execution> | ||
| 80 | + <id>sign-artifacts</id> | ||
| 81 | + <phase>verify</phase> | ||
| 82 | + <goals> | ||
| 83 | + <goal>sign</goal> | ||
| 84 | + </goals> | ||
| 85 | + </execution> | ||
| 86 | + </executions> | ||
| 87 | + </plugin> | ||
| 88 | + <plugin> | ||
| 89 | + <groupId>org.sonatype.central</groupId> | ||
| 90 | + <artifactId>central-publishing-maven-plugin</artifactId> | ||
| 91 | + <version>0.7.0</version> | ||
| 92 | + <extensions>true</extensions> | ||
| 93 | + <configuration> | ||
| 94 | + <publishingServerId>central</publishingServerId> | ||
| 95 | + </configuration> | ||
| 96 | + </plugin> | ||
| 97 | + </plugins> | ||
| 98 | + </build> | ||
| 99 | +</project> |
sherpa-onnx/java-api/readme.md
0 → 100644
| 1 | +# User Guide | ||
| 2 | + | ||
| 3 | +*Applicable to Windows / macOS / Linux (using Windows as an example for dynamic library loading)* | ||
| 4 | + | ||
| 5 | +## 1. Prerequisites | ||
| 6 | + | ||
| 7 | +* Java 1.8+ environment | ||
| 8 | +* Download and prepare the following: | ||
| 9 | + | ||
| 10 | + * Sherpa-ONNX Java API (Maven dependency) | ||
| 11 | + * Kokoro TTS model files (including `model.onnx`, etc.) | ||
| 12 | + | ||
| 13 | +--- | ||
| 14 | + | ||
| 15 | +## 2. Add Maven Dependency | ||
| 16 | + | ||
| 17 | +In your `pom.xml`, add: | ||
| 18 | + | ||
| 19 | +```xml | ||
| 20 | +<dependency> | ||
| 21 | + <groupId>com.litongjava</groupId> | ||
| 22 | + <artifactId>sherpa-onnx-java-api</artifactId> | ||
| 23 | + <version>1.0.1</version> | ||
| 24 | +</dependency> | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +--- | ||
| 28 | + | ||
| 29 | +## 3. Obtain and Configure Native Dynamic Libraries (JNI) | ||
| 30 | + | ||
| 31 | +### 3.1 Install ONNX Runtime | ||
| 32 | + | ||
| 33 | +#### Windows 10 | ||
| 34 | + | ||
| 35 | +Starting from Windows 10 v1809 and all versions of Windows 11, the system comes with built-in ONNX Runtime as part of Windows ML (WinRT API), exposed through Windows.AI.MachineLearning.dll. You can directly use WinML to load and run ONNX models without additional downloads or installations. | ||
| 36 | +[run-onnx-models](https://learn.microsoft.com/en-us/windows/ai/new-windows-ml/run-onnx-models) | ||
| 37 | + | ||
| 38 | +#### Linux | ||
| 39 | + | ||
| 40 | +Sherpa-ONNX does **not** bundle ONNX Runtime. To install it manually: | ||
| 41 | + | ||
| 42 | +1. Download the Linux x64 binary from Microsoft’s GitHub Releases: | ||
| 43 | + | ||
| 44 | + ```bash | ||
| 45 | + wget https://github.com/microsoft/onnxruntime/releases/download/v1.17.1/onnxruntime-linux-x64-1.17.1.tgz | ||
| 46 | + tar -xzf onnxruntime-linux-x64-1.17.1.tgz | ||
| 47 | + ``` | ||
| 48 | + | ||
| 49 | +2. Copy and symlink the library into a system directory: | ||
| 50 | + | ||
| 51 | + ```bash | ||
| 52 | + sudo cp onnxruntime-linux-x64-1.17.1/lib/libonnxruntime.so* /usr/local/lib/ | ||
| 53 | + sudo ln -sf /usr/local/lib/libonnxruntime.so.1.17.1 /usr/local/lib/libonnxruntime.so | ||
| 54 | + ``` | ||
| 55 | + | ||
| 56 | +3. Update the shared-library cache and verify: | ||
| 57 | + | ||
| 58 | + ```bash | ||
| 59 | + sudo ldconfig | ||
| 60 | + ldconfig -p | grep onnxruntime | ||
| 61 | + ``` | ||
| 62 | + | ||
| 63 | +#### macOS | ||
| 64 | + | ||
| 65 | +Sherpa-ONNX also requires you to install ONNX Runtime on macOS: | ||
| 66 | + | ||
| 67 | +1. Download the macOS ARM64 binary: | ||
| 68 | + | ||
| 69 | + ```bash | ||
| 70 | + wget https://github.com/microsoft/onnxruntime/releases/download/v1.17.1/onnxruntime-osx-arm64-1.17.1.tgz | ||
| 71 | + tar -xzf onnxruntime-osx-arm64-1.17.1.tgz | ||
| 72 | + ``` | ||
| 73 | + | ||
| 74 | +2. Copy the dylib into `/usr/local/lib`: | ||
| 75 | + | ||
| 76 | + ```bash | ||
| 77 | + sudo cp onnxruntime-osx-arm64-1.17.1/lib/libonnxruntime.1.17.1.dylib /usr/local/lib/ | ||
| 78 | + ``` | ||
| 79 | + | ||
| 80 | +3. Add `/usr/local/lib` to `dyld`’s search path: | ||
| 81 | + | ||
| 82 | + ```bash | ||
| 83 | + export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH | ||
| 84 | + ``` | ||
| 85 | + | ||
| 86 | +4. Verify with `otool`: | ||
| 87 | + | ||
| 88 | + ```bash | ||
| 89 | + otool -L /Users/ping/lib/darwin_arm64/libsherpa-onnx-jni.dylib | ||
| 90 | + ``` | ||
| 91 | + | ||
| 92 | +--- | ||
| 93 | + | ||
| 94 | +### 3.2 Common Errors & Troubleshooting | ||
| 95 | + | ||
| 96 | +**Error Example:** | ||
| 97 | + | ||
| 98 | +```text | ||
| 99 | +Exception in thread "main" java.lang.UnsatisfiedLinkError: no sherpa-onnx-jni in java.library.path: ... | ||
| 100 | +``` | ||
| 101 | + | ||
| 102 | +This means the JVM couldn’t locate the native library in `java.library.path`. | ||
| 103 | + | ||
| 104 | +**Troubleshooting steps:** | ||
| 105 | + | ||
| 106 | +1. Ensure you downloaded the build matching your OS and architecture (e.g. win-x64 vs. arm64). | ||
| 107 | + | ||
| 108 | +2. Test with an absolute path: | ||
| 109 | + | ||
| 110 | + ```bash | ||
| 111 | + java -Djava.library.path=C:\full\path\to\jni -jar your-app.jar | ||
| 112 | + ``` | ||
| 113 | + | ||
| 114 | +3. Print or inspect `java.library.path` at runtime (e.g. `System.out.println(System.getProperty("java.library.path"));`). | ||
| 115 | + | ||
| 116 | +4. **Do not** hack the internal `sys_paths` via reflection (it may throw `NoSuchFieldException`). Use `-Djava.library.path` instead. | ||
| 117 | + | ||
| 118 | +--- | ||
| 119 | + | ||
| 120 | +## 4. Download & Prepare the Kokoro Model | ||
| 121 | + | ||
| 122 | +Fetch the model package from the official release (example: Kokoro v0.19 English): | ||
| 123 | + | ||
| 124 | +``` | ||
| 125 | +https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/kokoro.html | ||
| 126 | +``` | ||
| 127 | + | ||
| 128 | +```bash | ||
| 129 | +# Download (manually or via script) | ||
| 130 | +wget https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/kokoro-en-v0_19.tar.bz2 | ||
| 131 | + | ||
| 132 | +# Extract | ||
| 133 | +tar -xjf kokoro-en-v0_19.tar.bz2 | ||
| 134 | + | ||
| 135 | +# Inspect | ||
| 136 | +ls -lh kokoro-en-v0_19/ | ||
| 137 | +``` | ||
| 138 | + | ||
| 139 | +You should see: | ||
| 140 | + | ||
| 141 | +``` | ||
| 142 | +LICENSE | ||
| 143 | +README.md | ||
| 144 | +espeak-ng-data/ # speech data directory | ||
| 145 | +model.onnx # TTS model | ||
| 146 | +tokens.txt # token mapping | ||
| 147 | +voices.bin # voice embeddings | ||
| 148 | +``` | ||
| 149 | + | ||
| 150 | +Make sure your Java code points to these files (using either relative or absolute paths). | ||
| 151 | + | ||
| 152 | +--- | ||
| 153 | + | ||
| 154 | +## 5. Test Code (Java Example) | ||
| 155 | + | ||
| 156 | +```java | ||
| 157 | +package com.litongjava.linux.tts; | ||
| 158 | + | ||
| 159 | +import com.k2fsa.sherpa.onnx.GeneratedAudio; | ||
| 160 | +import com.k2fsa.sherpa.onnx.OfflineTts; | ||
| 161 | +import com.k2fsa.sherpa.onnx.OfflineTtsConfig; | ||
| 162 | +import com.k2fsa.sherpa.onnx.OfflineTtsKokoroModelConfig; | ||
| 163 | +import com.k2fsa.sherpa.onnx.OfflineTtsModelConfig; | ||
| 164 | + | ||
| 165 | +public class NonStreamingTtsKokoroEn { | ||
| 166 | + public static void main(String[] args) { | ||
| 167 | + String model = "./kokoro-en-v0_19/model.onnx"; | ||
| 168 | + String voices = "./kokoro-en-v0_19/voices.bin"; | ||
| 169 | + String tokens = "./kokoro-en-v0_19/tokens.txt"; | ||
| 170 | + String dataDir = "./kokoro-en-v0_19/espeak-ng-data"; | ||
| 171 | + String text = "Today as always, men fall into two groups: slaves and free men. Whoever does not have" | ||
| 172 | + + " two-thirds of his day for himself, is a slave, whatever he may be: a statesman, a" | ||
| 173 | + + " businessman, an official, or a scholar."; | ||
| 174 | + | ||
| 175 | + OfflineTtsKokoroModelConfig kokoroConfig = OfflineTtsKokoroModelConfig.builder() | ||
| 176 | + .setModel(model) | ||
| 177 | + .setVoices(voices) | ||
| 178 | + .setTokens(tokens) | ||
| 179 | + .setDataDir(dataDir) | ||
| 180 | + .build(); | ||
| 181 | + | ||
| 182 | + OfflineTtsModelConfig modelConfig = OfflineTtsModelConfig.builder() | ||
| 183 | + .setKokoro(kokoroConfig) | ||
| 184 | + .setNumThreads(2) | ||
| 185 | + .setDebug(true) | ||
| 186 | + .build(); | ||
| 187 | + | ||
| 188 | + OfflineTtsConfig config = OfflineTtsConfig.builder() | ||
| 189 | + .setModel(modelConfig) | ||
| 190 | + .build(); | ||
| 191 | + | ||
| 192 | + OfflineTts tts = new OfflineTts(config); | ||
| 193 | + | ||
| 194 | + int sid = 0; | ||
| 195 | + float speed = 1.0f; | ||
| 196 | + long start = System.currentTimeMillis(); | ||
| 197 | + GeneratedAudio audio = tts.generate(text, sid, speed); | ||
| 198 | + long stop = System.currentTimeMillis(); | ||
| 199 | + | ||
| 200 | + float elapsed = (stop - start) / 1000.0f; | ||
| 201 | + float duration = audio.getSamples().length / (float) audio.getSampleRate(); | ||
| 202 | + float rtf = elapsed / duration; | ||
| 203 | + | ||
| 204 | + String outFile = "tts-kokoro-en.wav"; | ||
| 205 | + audio.save(outFile); | ||
| 206 | + | ||
| 207 | + System.out.printf("-- elapsed : %.3f seconds%n", elapsed); | ||
| 208 | + System.out.printf("-- audio duration : %.3f seconds%n", duration); | ||
| 209 | + System.out.printf("-- real-time factor : %.3f%n", rtf); | ||
| 210 | + System.out.printf("-- text : %s%n", text); | ||
| 211 | + System.out.printf("-- Saved to : %s%n", outFile); | ||
| 212 | + | ||
| 213 | + tts.release(); | ||
| 214 | + } | ||
| 215 | +} | ||
| 216 | +``` | ||
| 217 | + | ||
| 218 | +### Output Explanation | ||
| 219 | + | ||
| 220 | +After successful execution, you should see something like: | ||
| 221 | + | ||
| 222 | +``` | ||
| 223 | +-- elapsed : 6.739 seconds | ||
| 224 | +-- audio duration : 6.739 seconds | ||
| 225 | +-- real-time factor : 0.563 | ||
| 226 | +-- text : ... | ||
| 227 | +-- Saved to : tts-kokoro-en.wav | ||
| 228 | +``` | ||
| 229 | + | ||
| 230 | +A file named `tts-kokoro-en.wav` will appear in the current directory—play it with any audio player to verify. |
sherpa-onnx/java-api/readme.zh.md
0 → 100644
| 1 | +# 使用指南 | ||
| 2 | + | ||
| 3 | +*适用于 Windows / macOS / Linux(以 Windows 为例说明动态库加载)* | ||
| 4 | + | ||
| 5 | +## 1. 前提条件 | ||
| 6 | + | ||
| 7 | +* Java 1.8+ 环境 | ||
| 8 | +* 下载并准备好以下内容: | ||
| 9 | + * Sherpa-ONNX Java API(Maven 依赖) | ||
| 10 | + * Kokoro TTS 模型文件(包含 `model.onnx` 等) | ||
| 11 | + | ||
| 12 | +--- | ||
| 13 | + | ||
| 14 | +## 2. 添加 Maven 依赖 | ||
| 15 | + | ||
| 16 | +在你的 `pom.xml` 中添加如下依赖: | ||
| 17 | + | ||
| 18 | +```xml | ||
| 19 | +<dependency> | ||
| 20 | + <groupId>com.litongjava</groupId> | ||
| 21 | + <artifactId>sherpa-onnx-java-api</artifactId> | ||
| 22 | + <version>1.0.1</version> | ||
| 23 | +</dependency> | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +--- | ||
| 27 | + | ||
| 28 | +## 3. 获取并配置本地动态链接库(JNI) | ||
| 29 | + | ||
| 30 | +### 3.1 安装 ONNX Runtime | ||
| 31 | + | ||
| 32 | +#### 1. Windows 11 | ||
| 33 | + | ||
| 34 | +Starting from Windows 10 v1809 and all versions of Windows 11, the system comes with built-in ONNX Runtime as part of Windows ML (WinRT API), exposed through Windows.AI.MachineLearning.dll. You can directly use WinML to load and run ONNX models without additional downloads or installations. | ||
| 35 | +(run-onnx-models)[https://learn.microsoft.com/en-us/windows/ai/new-windows-ml/run-onnx-models] | ||
| 36 | + | ||
| 37 | +#### 2. Linux | ||
| 38 | + | ||
| 39 | +Sherpa-ONNX 并不包含 ONNX Runtime,需要手动下载并配置: | ||
| 40 | + | ||
| 41 | +1. 从微软官方 GitHub Releases 下载 Linux 64 位二进制包: | ||
| 42 | + | ||
| 43 | + ```bash | ||
| 44 | + wget https://github.com/microsoft/onnxruntime/releases/download/v1.17.1/onnxruntime-linux-x64-1.17.1.tgz | ||
| 45 | + tar -xzf onnxruntime-linux-x64-1.17.1.tgz | ||
| 46 | + ``` | ||
| 47 | +2. 将解压后的 `libonnxruntime.so` 文件复制到系统库目录,并创建软链接: | ||
| 48 | + | ||
| 49 | + ```bash | ||
| 50 | + sudo cp onnxruntime-linux-x64-1.17.1/lib/libonnxruntime.so* /usr/local/lib/ | ||
| 51 | + sudo ln -sf /usr/local/lib/libonnxruntime.so.1.17.1 /usr/local/lib/libonnxruntime.so | ||
| 52 | + ``` | ||
| 53 | +3. 更新共享库缓存并验证安装: | ||
| 54 | + | ||
| 55 | + ```bash | ||
| 56 | + sudo ldconfig | ||
| 57 | + ldconfig -p | grep onnxruntime | ||
| 58 | + ``` | ||
| 59 | + | ||
| 60 | +#### 3. macOS | ||
| 61 | + | ||
| 62 | +Sherpa-ONNX 同样不包含 ONNX Runtime,需要从官方获取并配置: | ||
| 63 | + | ||
| 64 | +1. 下载 macOS ARM64 版本二进制包: | ||
| 65 | + | ||
| 66 | + ```bash | ||
| 67 | + wget https://github.com/microsoft/onnxruntime/releases/download/v1.17.1/onnxruntime-osx-arm64-1.17.1.tgz | ||
| 68 | + tar -xzf onnxruntime-osx-arm64-1.17.1.tgz | ||
| 69 | + ``` | ||
| 70 | +2. 将 `libonnxruntime.1.17.1.dylib` 复制到 `/usr/local/lib`: | ||
| 71 | + | ||
| 72 | + ```bash | ||
| 73 | + sudo cp onnxruntime-osx-arm64-1.17.1/lib/libonnxruntime.1.17.1.dylib /usr/local/lib/ | ||
| 74 | + ``` | ||
| 75 | +3. 将 `/usr/local/lib` 添加到 `dyld` 的搜索路径: | ||
| 76 | + | ||
| 77 | + ```bash | ||
| 78 | + export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH | ||
| 79 | + ``` | ||
| 80 | +4. 使用 `otool` 验证: | ||
| 81 | + | ||
| 82 | + ```bash | ||
| 83 | + otool -L /Users/ping/lib/darwin_arm64/libsherpa-onnx-jni.dylib | ||
| 84 | + ``` | ||
| 85 | +--- | ||
| 86 | + | ||
| 87 | + | ||
| 88 | +### 3.2 常见错误与排查 | ||
| 89 | + | ||
| 90 | +**错误示例:** | ||
| 91 | + | ||
| 92 | +```text | ||
| 93 | +Exception in thread "main" java.lang.UnsatisfiedLinkError: no sherpa-onnx-jni in java.library.path: ... | ||
| 94 | +``` | ||
| 95 | + | ||
| 96 | +说明 JVM 没有在 `java.library.path` 中找到本地库。 | ||
| 97 | + | ||
| 98 | +排查步骤: | ||
| 99 | + | ||
| 100 | +1. 确认下载的是与你操作系统与架构匹配的版本(如 win-x64 vs arm64 等)。 | ||
| 101 | +2. 用绝对路径测试:将 `.dll` 放在某个目录并运行: | ||
| 102 | + | ||
| 103 | + ```sh | ||
| 104 | + java -Djava.library.path=C:\full\path\to\jni -jar your-app.jar | ||
| 105 | + ``` | ||
| 106 | +3. 打印或检查 `java.library.path` 内容(示例代码里可输出 `System.getProperty("java.library.path")`)。 | ||
| 107 | +4. 避免通过反射修改 `sys_paths`(不要尝试 hack `java.library.path` 的内部字段,容易引发 `NoSuchFieldException: sys_paths`,建议直接用 `-Djava.library.path`)。 | ||
| 108 | + | ||
| 109 | +--- | ||
| 110 | + | ||
| 111 | +## 4. 下载并准备 Kokoro 模型 | ||
| 112 | + | ||
| 113 | +从官方 release 获取模型包(以英文 Kokoro v0.19 为例): | ||
| 114 | +``` | ||
| 115 | +https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/kokoro.html | ||
| 116 | +``` | ||
| 117 | + | ||
| 118 | +```sh | ||
| 119 | +# 下载(手工或脚本) | ||
| 120 | +# 例如从 GitHub releases: | ||
| 121 | +wget https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/kokoro-en-v0_19.tar.bz2 | ||
| 122 | + | ||
| 123 | +# 解压 | ||
| 124 | +tar -xjf kokoro-en-v0_19.tar.bz2 | ||
| 125 | + | ||
| 126 | +# 查看结构 | ||
| 127 | +ls -lh kokoro-en-v0_19/ | ||
| 128 | +``` | ||
| 129 | + | ||
| 130 | +该目录结构示例(解压后应包含): | ||
| 131 | + | ||
| 132 | +``` | ||
| 133 | +LICENSE | ||
| 134 | +README.md | ||
| 135 | +espeak-ng-data/ # 语音数据目录 | ||
| 136 | +model.onnx # TTS 模型 | ||
| 137 | +tokens.txt # token 映射 | ||
| 138 | +voices.bin # voice embedding | ||
| 139 | +``` | ||
| 140 | + | ||
| 141 | +确保这些路径在你的 Java 程序中指向正确的位置(相对或绝对皆可)。 | ||
| 142 | + | ||
| 143 | +--- | ||
| 144 | + | ||
| 145 | +## 5. 测试代码(Java 示例) | ||
| 146 | + | ||
| 147 | +```java | ||
| 148 | +package com.litongjava.linux.tts; | ||
| 149 | + | ||
| 150 | +import com.k2fsa.sherpa.onnx.GeneratedAudio; | ||
| 151 | +import com.k2fsa.sherpa.onnx.OfflineTts; | ||
| 152 | +import com.k2fsa.sherpa.onnx.OfflineTtsConfig; | ||
| 153 | +import com.k2fsa.sherpa.onnx.OfflineTtsKokoroModelConfig; | ||
| 154 | +import com.k2fsa.sherpa.onnx.OfflineTtsModelConfig; | ||
| 155 | + | ||
| 156 | +public class NonStreamingTtsKokoroEn { | ||
| 157 | + public static void main(String[] args) { | ||
| 158 | + String model = "./kokoro-en-v0_19/model.onnx"; | ||
| 159 | + String voices = "./kokoro-en-v0_19/voices.bin"; | ||
| 160 | + String tokens = "./kokoro-en-v0_19/tokens.txt"; | ||
| 161 | + String dataDir = "./kokoro-en-v0_19/espeak-ng-data"; | ||
| 162 | + String text = "Today as always, men fall into two groups: slaves and free men. Whoever does not have" | ||
| 163 | + + " two-thirds of his day for himself, is a slave, whatever he may be: a statesman, a" | ||
| 164 | + + " businessman, an official, or a scholar."; | ||
| 165 | + | ||
| 166 | + OfflineTtsKokoroModelConfig kokoroModelConfig = OfflineTtsKokoroModelConfig.builder() | ||
| 167 | + .setModel(model) | ||
| 168 | + .setVoices(voices) | ||
| 169 | + .setTokens(tokens) | ||
| 170 | + .setDataDir(dataDir) | ||
| 171 | + .build(); | ||
| 172 | + | ||
| 173 | + OfflineTtsModelConfig modelConfig = OfflineTtsModelConfig.builder() | ||
| 174 | + .setKokoro(kokoroModelConfig) | ||
| 175 | + .setNumThreads(2) | ||
| 176 | + .setDebug(true) | ||
| 177 | + .build(); | ||
| 178 | + | ||
| 179 | + OfflineTtsConfig config = OfflineTtsConfig.builder() | ||
| 180 | + .setModel(modelConfig) | ||
| 181 | + .build(); | ||
| 182 | + | ||
| 183 | + OfflineTts tts = new OfflineTts(config); | ||
| 184 | + | ||
| 185 | + int sid = 0; | ||
| 186 | + float speed = 1.0f; | ||
| 187 | + long start = System.currentTimeMillis(); | ||
| 188 | + GeneratedAudio audio = tts.generate(text, sid, speed); | ||
| 189 | + long stop = System.currentTimeMillis(); | ||
| 190 | + | ||
| 191 | + float timeElapsedSeconds = (stop - start) / 1000.0f; | ||
| 192 | + float audioDuration = audio.getSamples().length / (float) audio.getSampleRate(); | ||
| 193 | + float real_time_factor = timeElapsedSeconds / audioDuration; | ||
| 194 | + | ||
| 195 | + String waveFilename = "tts-kokoro-en.wav"; | ||
| 196 | + audio.save(waveFilename); | ||
| 197 | + System.out.printf("-- elapsed : %.3f seconds\n", timeElapsedSeconds); | ||
| 198 | + System.out.printf("-- audio duration: %.3f seconds\n", audioDuration); | ||
| 199 | + System.out.printf("-- real-time factor (RTF): %.3f\n", real_time_factor); | ||
| 200 | + System.out.printf("-- text: %s\n", text); | ||
| 201 | + System.out.printf("-- Saved to %s\n", waveFilename); | ||
| 202 | + | ||
| 203 | + tts.release(); | ||
| 204 | + } | ||
| 205 | +} | ||
| 206 | +``` | ||
| 207 | + | ||
| 208 | +### 输出说明 | ||
| 209 | + | ||
| 210 | +成功执行后会输出类似: | ||
| 211 | + | ||
| 212 | +``` | ||
| 213 | +-- elapsed : 6.739 seconds | ||
| 214 | +-- audio duration: 6.739 seconds | ||
| 215 | +-- real-time factor (RTF): 0.563 | ||
| 216 | +-- text: ... | ||
| 217 | +-- Saved to tts-kokoro-en.wav | ||
| 218 | +``` | ||
| 219 | + | ||
| 220 | +并在当前目录生成 `tts-kokoro-en.wav`,可以用任意音频播放器播放验证。 | ||
| 221 | + | ||
| 222 | +--- |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class EndpointConfig { | ||
| 7 | - | ||
| 8 | - private final EndpointRule rule1; | ||
| 9 | - private final EndpointRule rule2; | ||
| 10 | - private final EndpointRule rule3; | ||
| 11 | - | ||
| 12 | - private EndpointConfig(Builder builder) { | ||
| 13 | - this.rule1 = builder.rule1; | ||
| 14 | - this.rule2 = builder.rule2; | ||
| 15 | - this.rule3 = builder.rule3; | ||
| 16 | - } | ||
| 17 | - | ||
| 18 | - public static Builder builder() { | ||
| 19 | - return new Builder(); | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - public EndpointRule getRule1() { | ||
| 23 | - return rule1; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public EndpointRule getRule2() { | ||
| 27 | - return rule2; | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - public EndpointRule getRule3() { | ||
| 31 | - return rule3; | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - public static class Builder { | ||
| 35 | - | ||
| 36 | - private EndpointRule rule1 = EndpointRule.builder(). | ||
| 37 | - setMustContainNonSilence(false). | ||
| 38 | - setMinTrailingSilence(2.4f). | ||
| 39 | - setMinUtteranceLength(0). | ||
| 40 | - build(); | ||
| 41 | - private EndpointRule rule2 = EndpointRule.builder(). | ||
| 42 | - setMustContainNonSilence(true). | ||
| 43 | - setMinTrailingSilence(1.4f). | ||
| 44 | - setMinUtteranceLength(0). | ||
| 45 | - build(); | ||
| 46 | - private EndpointRule rule3 = EndpointRule.builder(). | ||
| 47 | - setMustContainNonSilence(false). | ||
| 48 | - setMinTrailingSilence(0.0f). | ||
| 49 | - setMinUtteranceLength(20.0f). | ||
| 50 | - build(); | ||
| 51 | - | ||
| 52 | - public EndpointConfig build() { | ||
| 53 | - return new EndpointConfig(this); | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - public Builder setRule1(EndpointRule rule) { | ||
| 57 | - this.rule1 = rule; | ||
| 58 | - return this; | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - public Builder setRule2(EndpointRule rule) { | ||
| 62 | - this.rule2 = rule; | ||
| 63 | - return this; | ||
| 64 | - } | ||
| 65 | - | ||
| 66 | - public Builder setRul3(EndpointRule rule) { | ||
| 67 | - this.rule3 = rule; | ||
| 68 | - return this; | ||
| 69 | - } | ||
| 70 | - } | ||
| 71 | -} | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class EndpointConfig { | ||
| 7 | + | ||
| 8 | + private final EndpointRule rule1; | ||
| 9 | + private final EndpointRule rule2; | ||
| 10 | + private final EndpointRule rule3; | ||
| 11 | + | ||
| 12 | + private EndpointConfig(Builder builder) { | ||
| 13 | + this.rule1 = builder.rule1; | ||
| 14 | + this.rule2 = builder.rule2; | ||
| 15 | + this.rule3 = builder.rule3; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public static Builder builder() { | ||
| 19 | + return new Builder(); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public EndpointRule getRule1() { | ||
| 23 | + return rule1; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public EndpointRule getRule2() { | ||
| 27 | + return rule2; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public EndpointRule getRule3() { | ||
| 31 | + return rule3; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public static class Builder { | ||
| 35 | + | ||
| 36 | + private EndpointRule rule1 = EndpointRule.builder(). | ||
| 37 | + setMustContainNonSilence(false). | ||
| 38 | + setMinTrailingSilence(2.4f). | ||
| 39 | + setMinUtteranceLength(0). | ||
| 40 | + build(); | ||
| 41 | + private EndpointRule rule2 = EndpointRule.builder(). | ||
| 42 | + setMustContainNonSilence(true). | ||
| 43 | + setMinTrailingSilence(1.4f). | ||
| 44 | + setMinUtteranceLength(0). | ||
| 45 | + build(); | ||
| 46 | + private EndpointRule rule3 = EndpointRule.builder(). | ||
| 47 | + setMustContainNonSilence(false). | ||
| 48 | + setMinTrailingSilence(0.0f). | ||
| 49 | + setMinUtteranceLength(20.0f). | ||
| 50 | + build(); | ||
| 51 | + | ||
| 52 | + public EndpointConfig build() { | ||
| 53 | + return new EndpointConfig(this); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + public Builder setRule1(EndpointRule rule) { | ||
| 57 | + this.rule1 = rule; | ||
| 58 | + return this; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public Builder setRule2(EndpointRule rule) { | ||
| 62 | + this.rule2 = rule; | ||
| 63 | + return this; | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + public Builder setRule3(EndpointRule rule) { | ||
| 67 | + this.rule3 = rule; | ||
| 68 | + return this; | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | +} |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class EndpointRule { | ||
| 7 | - | ||
| 8 | - private final boolean mustContainNonSilence; | ||
| 9 | - private final float minTrailingSilence; | ||
| 10 | - private final float minUtteranceLength; | ||
| 11 | - | ||
| 12 | - private EndpointRule(Builder builder) { | ||
| 13 | - this.mustContainNonSilence = builder.mustContainNonSilence; | ||
| 14 | - this.minTrailingSilence = builder.minTrailingSilence; | ||
| 15 | - this.minUtteranceLength = builder.minUtteranceLength; | ||
| 16 | - } | ||
| 17 | - | ||
| 18 | - public static Builder builder() { | ||
| 19 | - return new Builder(); | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - public float getMinTrailingSilence() { | ||
| 23 | - return minTrailingSilence; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public float getMinUtteranceLength() { | ||
| 27 | - return minUtteranceLength; | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - public boolean getMustContainNonSilence() { | ||
| 31 | - return mustContainNonSilence; | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - public static class Builder { | ||
| 35 | - private boolean mustContainNonSilence = false; | ||
| 36 | - private float minTrailingSilence = 0; | ||
| 37 | - private float minUtteranceLength = 0; | ||
| 38 | - | ||
| 39 | - public EndpointRule build() { | ||
| 40 | - return new EndpointRule(this); | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - public Builder setMustContainNonSilence(boolean mustContainNonSilence) { | ||
| 44 | - this.mustContainNonSilence = mustContainNonSilence; | ||
| 45 | - return this; | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - public Builder setMinTrailingSilence(float minTrailingSilence) { | ||
| 49 | - this.minTrailingSilence = minTrailingSilence; | ||
| 50 | - return this; | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - public Builder setMinUtteranceLength(float minUtteranceLength) { | ||
| 54 | - this.minUtteranceLength = minUtteranceLength; | ||
| 55 | - return this; | ||
| 56 | - } | ||
| 57 | - } | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class EndpointRule { | ||
| 7 | + | ||
| 8 | + private final boolean mustContainNonSilence; | ||
| 9 | + private final float minTrailingSilence; | ||
| 10 | + private final float minUtteranceLength; | ||
| 11 | + | ||
| 12 | + private EndpointRule(Builder builder) { | ||
| 13 | + this.mustContainNonSilence = builder.mustContainNonSilence; | ||
| 14 | + this.minTrailingSilence = builder.minTrailingSilence; | ||
| 15 | + this.minUtteranceLength = builder.minUtteranceLength; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public static Builder builder() { | ||
| 19 | + return new Builder(); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public float getMinTrailingSilence() { | ||
| 23 | + return minTrailingSilence; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public float getMinUtteranceLength() { | ||
| 27 | + return minUtteranceLength; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public boolean getMustContainNonSilence() { | ||
| 31 | + return mustContainNonSilence; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public static class Builder { | ||
| 35 | + private boolean mustContainNonSilence = false; | ||
| 36 | + private float minTrailingSilence = 0; | ||
| 37 | + private float minUtteranceLength = 0; | ||
| 38 | + | ||
| 39 | + public EndpointRule build() { | ||
| 40 | + return new EndpointRule(this); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + public Builder setMustContainNonSilence(boolean mustContainNonSilence) { | ||
| 44 | + this.mustContainNonSilence = mustContainNonSilence; | ||
| 45 | + return this; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public Builder setMinTrailingSilence(float minTrailingSilence) { | ||
| 49 | + this.minTrailingSilence = minTrailingSilence; | ||
| 50 | + return this; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public Builder setMinUtteranceLength(float minUtteranceLength) { | ||
| 54 | + this.minUtteranceLength = minUtteranceLength; | ||
| 55 | + return this; | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | } | 58 | } |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class FeatureConfig { | ||
| 7 | - private final int sampleRate; | ||
| 8 | - private final int featureDim; | ||
| 9 | - private final float dither; | ||
| 10 | - | ||
| 11 | - private FeatureConfig(Builder builder) { | ||
| 12 | - this.sampleRate = builder.sampleRate; | ||
| 13 | - this.featureDim = builder.featureDim; | ||
| 14 | - this.dither = builder.dither; | ||
| 15 | - } | ||
| 16 | - | ||
| 17 | - public static Builder builder() { | ||
| 18 | - return new Builder(); | ||
| 19 | - } | ||
| 20 | - | ||
| 21 | - public int getSampleRate() { | ||
| 22 | - return sampleRate; | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | - public int getFeatureDim() { | ||
| 26 | - return featureDim; | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | - public float getDither() { | ||
| 30 | - return dither; | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public static class Builder { | ||
| 34 | - private int sampleRate = 16000; | ||
| 35 | - private int featureDim = 80; | ||
| 36 | - private float dither = 0.0f; | ||
| 37 | - | ||
| 38 | - public FeatureConfig build() { | ||
| 39 | - return new FeatureConfig(this); | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - public Builder setSampleRate(int sampleRate) { | ||
| 43 | - this.sampleRate = sampleRate; | ||
| 44 | - return this; | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - public Builder setFeatureDim(int featureDim) { | ||
| 48 | - this.featureDim = featureDim; | ||
| 49 | - return this; | ||
| 50 | - } | ||
| 51 | - public Builder setDither(float dither) { | ||
| 52 | - this.dither = dither; | ||
| 53 | - return this; | ||
| 54 | - } | ||
| 55 | - } | ||
| 56 | -} | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class FeatureConfig { | ||
| 7 | + private final int sampleRate; | ||
| 8 | + private final int featureDim; | ||
| 9 | + private final float dither; | ||
| 10 | + | ||
| 11 | + private FeatureConfig(Builder builder) { | ||
| 12 | + this.sampleRate = builder.sampleRate; | ||
| 13 | + this.featureDim = builder.featureDim; | ||
| 14 | + this.dither = builder.dither; | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + public static Builder builder() { | ||
| 18 | + return new Builder(); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + public int getSampleRate() { | ||
| 22 | + return sampleRate; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public int getFeatureDim() { | ||
| 26 | + return featureDim; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + public float getDither() { | ||
| 30 | + return dither; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public static class Builder { | ||
| 34 | + private int sampleRate = 16000; | ||
| 35 | + private int featureDim = 80; | ||
| 36 | + private float dither = 0.0f; | ||
| 37 | + | ||
| 38 | + public FeatureConfig build() { | ||
| 39 | + return new FeatureConfig(this); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public Builder setSampleRate(int sampleRate) { | ||
| 43 | + this.sampleRate = sampleRate; | ||
| 44 | + return this; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public Builder setFeatureDim(int featureDim) { | ||
| 48 | + this.featureDim = featureDim; | ||
| 49 | + return this; | ||
| 50 | + } | ||
| 51 | + public Builder setDither(float dither) { | ||
| 52 | + this.dither = dither; | ||
| 53 | + return this; | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | +} |
| 1 | package com.k2fsa.sherpa.onnx; | 1 | package com.k2fsa.sherpa.onnx; |
| 2 | 2 | ||
| 3 | +import com.k2fsa.sherpa.onnx.utils.LibraryUtils; | ||
| 4 | + | ||
| 3 | public class LibraryLoader { | 5 | public class LibraryLoader { |
| 4 | private static volatile boolean autoLoadEnabled = true; | 6 | private static volatile boolean autoLoadEnabled = true; |
| 5 | private static volatile boolean isLoaded = false; | 7 | private static volatile boolean isLoaded = false; |
| 6 | 8 | ||
| 7 | static synchronized void loadLibrary() { | 9 | static synchronized void loadLibrary() { |
| 8 | if (!isLoaded) { | 10 | if (!isLoaded) { |
| 9 | - System.loadLibrary("sherpa-onnx-jni"); | 11 | + LibraryUtils.load(); |
| 10 | isLoaded = true; | 12 | isLoaded = true; |
| 11 | } | 13 | } |
| 12 | } | 14 | } |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineLMConfig { | ||
| 7 | - | ||
| 8 | - private final String model; | ||
| 9 | - private final float scale; | ||
| 10 | - | ||
| 11 | - private OnlineLMConfig(Builder builder) { | ||
| 12 | - this.model = builder.model; | ||
| 13 | - this.scale = builder.scale; | ||
| 14 | - } | ||
| 15 | - | ||
| 16 | - public static Builder builder() { | ||
| 17 | - return new Builder(); | ||
| 18 | - } | ||
| 19 | - | ||
| 20 | - public String getModel() { | ||
| 21 | - return model; | ||
| 22 | - } | ||
| 23 | - | ||
| 24 | - public float getScale() { | ||
| 25 | - return scale; | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - public static class Builder { | ||
| 29 | - private String model = ""; | ||
| 30 | - private float scale = 1.0f; | ||
| 31 | - | ||
| 32 | - public OnlineLMConfig build() { | ||
| 33 | - return new OnlineLMConfig(this); | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - public Builder setModel(String model) { | ||
| 37 | - this.model = model; | ||
| 38 | - return this; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - public Builder setScale(float scale) { | ||
| 42 | - this.scale = scale; | ||
| 43 | - return this; | ||
| 44 | - } | ||
| 45 | - } | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineLMConfig { | ||
| 7 | + | ||
| 8 | + private final String model; | ||
| 9 | + private final float scale; | ||
| 10 | + | ||
| 11 | + private OnlineLMConfig(Builder builder) { | ||
| 12 | + this.model = builder.model; | ||
| 13 | + this.scale = builder.scale; | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public static Builder builder() { | ||
| 17 | + return new Builder(); | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public String getModel() { | ||
| 21 | + return model; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public float getScale() { | ||
| 25 | + return scale; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + public static class Builder { | ||
| 29 | + private String model = ""; | ||
| 30 | + private float scale = 1.0f; | ||
| 31 | + | ||
| 32 | + public OnlineLMConfig build() { | ||
| 33 | + return new OnlineLMConfig(this); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + public Builder setModel(String model) { | ||
| 37 | + this.model = model; | ||
| 38 | + return this; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public Builder setScale(float scale) { | ||
| 42 | + this.scale = scale; | ||
| 43 | + return this; | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | } | 46 | } |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineModelConfig { | ||
| 7 | - private final OnlineTransducerModelConfig transducer; | ||
| 8 | - private final OnlineParaformerModelConfig paraformer; | ||
| 9 | - private final OnlineZipformer2CtcModelConfig zipformer2Ctc; | ||
| 10 | - private final OnlineNeMoCtcModelConfig neMoCtc; | ||
| 11 | - private final String tokens; | ||
| 12 | - private final int numThreads; | ||
| 13 | - private final boolean debug; | ||
| 14 | - private final String provider; | ||
| 15 | - private final String modelType; | ||
| 16 | - private final String modelingUnit; | ||
| 17 | - private final String bpeVocab; | ||
| 18 | - | ||
| 19 | - private OnlineModelConfig(Builder builder) { | ||
| 20 | - this.transducer = builder.transducer; | ||
| 21 | - this.paraformer = builder.paraformer; | ||
| 22 | - this.zipformer2Ctc = builder.zipformer2Ctc; | ||
| 23 | - this.neMoCtc = builder.neMoCtc; | ||
| 24 | - this.tokens = builder.tokens; | ||
| 25 | - this.numThreads = builder.numThreads; | ||
| 26 | - this.debug = builder.debug; | ||
| 27 | - this.provider = builder.provider; | ||
| 28 | - this.modelType = builder.modelType; | ||
| 29 | - this.modelingUnit = builder.modelingUnit; | ||
| 30 | - this.bpeVocab = builder.bpeVocab; | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public static Builder builder() { | ||
| 34 | - return new Builder(); | ||
| 35 | - } | ||
| 36 | - | ||
| 37 | - public OnlineParaformerModelConfig getParaformer() { | ||
| 38 | - return paraformer; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - public OnlineTransducerModelConfig getTransducer() { | ||
| 42 | - return transducer; | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - public OnlineZipformer2CtcModelConfig getZipformer2Ctc() { | ||
| 46 | - return zipformer2Ctc; | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - public OnlineNeMoCtcModelConfig getNeMoCtc() { | ||
| 50 | - return neMoCtc; | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - public String getTokens() { | ||
| 54 | - return tokens; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - public int getNumThreads() { | ||
| 58 | - return numThreads; | ||
| 59 | - } | ||
| 60 | - | ||
| 61 | - public boolean getDebug() { | ||
| 62 | - return debug; | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - public String getProvider() { | ||
| 66 | - return provider; | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - public String getModelType() { | ||
| 70 | - return modelType; | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - public String getModelingUnit() { | ||
| 74 | - return modelingUnit; | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - public String getBpeVocab() { | ||
| 78 | - return bpeVocab; | ||
| 79 | - } | ||
| 80 | - | ||
| 81 | - public static class Builder { | ||
| 82 | - private OnlineParaformerModelConfig paraformer = OnlineParaformerModelConfig.builder().build(); | ||
| 83 | - private OnlineTransducerModelConfig transducer = OnlineTransducerModelConfig.builder().build(); | ||
| 84 | - private OnlineZipformer2CtcModelConfig zipformer2Ctc = OnlineZipformer2CtcModelConfig.builder().build(); | ||
| 85 | - private OnlineNeMoCtcModelConfig neMoCtc = OnlineNeMoCtcModelConfig.builder().build(); | ||
| 86 | - private String tokens = ""; | ||
| 87 | - private int numThreads = 1; | ||
| 88 | - private boolean debug = true; | ||
| 89 | - private String provider = "cpu"; | ||
| 90 | - private String modelType = ""; | ||
| 91 | - private String modelingUnit = "cjkchar"; | ||
| 92 | - private String bpeVocab = ""; | ||
| 93 | - | ||
| 94 | - public OnlineModelConfig build() { | ||
| 95 | - return new OnlineModelConfig(this); | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - public Builder setTransducer(OnlineTransducerModelConfig transducer) { | ||
| 99 | - this.transducer = transducer; | ||
| 100 | - return this; | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - public Builder setParaformer(OnlineParaformerModelConfig paraformer) { | ||
| 104 | - this.paraformer = paraformer; | ||
| 105 | - return this; | ||
| 106 | - } | ||
| 107 | - | ||
| 108 | - public Builder setZipformer2Ctc(OnlineZipformer2CtcModelConfig zipformer2Ctc) { | ||
| 109 | - this.zipformer2Ctc = zipformer2Ctc; | ||
| 110 | - return this; | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - public Builder setNeMoCtc(OnlineNeMoCtcModelConfig neMoCtc) { | ||
| 114 | - this.neMoCtc = neMoCtc; | ||
| 115 | - return this; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - public Builder setTokens(String tokens) { | ||
| 119 | - this.tokens = tokens; | ||
| 120 | - return this; | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - public Builder setNumThreads(int numThreads) { | ||
| 124 | - this.numThreads = numThreads; | ||
| 125 | - return this; | ||
| 126 | - } | ||
| 127 | - | ||
| 128 | - public Builder setDebug(boolean debug) { | ||
| 129 | - this.debug = debug; | ||
| 130 | - return this; | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - public Builder setProvider(String provider) { | ||
| 134 | - this.provider = provider; | ||
| 135 | - return this; | ||
| 136 | - } | ||
| 137 | - | ||
| 138 | - public Builder setModelType(String modelType) { | ||
| 139 | - this.modelType = modelType; | ||
| 140 | - return this; | ||
| 141 | - } | ||
| 142 | - | ||
| 143 | - public Builder setModelingUnit(String modelingUnit) { | ||
| 144 | - this.modelingUnit = modelingUnit; | ||
| 145 | - return this; | ||
| 146 | - } | ||
| 147 | - | ||
| 148 | - public Builder setBpeVocab(String bpeVocab) { | ||
| 149 | - this.bpeVocab = bpeVocab; | ||
| 150 | - return this; | ||
| 151 | - } | ||
| 152 | - } | ||
| 153 | -} | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineModelConfig { | ||
| 7 | + private final OnlineTransducerModelConfig transducer; | ||
| 8 | + private final OnlineParaformerModelConfig paraformer; | ||
| 9 | + private final OnlineZipformer2CtcModelConfig zipformer2Ctc; | ||
| 10 | + private final OnlineNeMoCtcModelConfig neMoCtc; | ||
| 11 | + private final String tokens; | ||
| 12 | + private final int numThreads; | ||
| 13 | + private final boolean debug; | ||
| 14 | + private final String provider; | ||
| 15 | + private final String modelType; | ||
| 16 | + private final String modelingUnit; | ||
| 17 | + private final String bpeVocab; | ||
| 18 | + | ||
| 19 | + private OnlineModelConfig(Builder builder) { | ||
| 20 | + this.transducer = builder.transducer; | ||
| 21 | + this.paraformer = builder.paraformer; | ||
| 22 | + this.zipformer2Ctc = builder.zipformer2Ctc; | ||
| 23 | + this.neMoCtc = builder.neMoCtc; | ||
| 24 | + this.tokens = builder.tokens; | ||
| 25 | + this.numThreads = builder.numThreads; | ||
| 26 | + this.debug = builder.debug; | ||
| 27 | + this.provider = builder.provider; | ||
| 28 | + this.modelType = builder.modelType; | ||
| 29 | + this.modelingUnit = builder.modelingUnit; | ||
| 30 | + this.bpeVocab = builder.bpeVocab; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public static Builder builder() { | ||
| 34 | + return new Builder(); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public OnlineParaformerModelConfig getParaformer() { | ||
| 38 | + return paraformer; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public OnlineTransducerModelConfig getTransducer() { | ||
| 42 | + return transducer; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public OnlineZipformer2CtcModelConfig getZipformer2Ctc() { | ||
| 46 | + return zipformer2Ctc; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + public OnlineNeMoCtcModelConfig getNeMoCtc() { | ||
| 50 | + return neMoCtc; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public String getTokens() { | ||
| 54 | + return tokens; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + public int getNumThreads() { | ||
| 58 | + return numThreads; | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public boolean getDebug() { | ||
| 62 | + return debug; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + public String getProvider() { | ||
| 66 | + return provider; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + public String getModelType() { | ||
| 70 | + return modelType; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + public String getModelingUnit() { | ||
| 74 | + return modelingUnit; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + public String getBpeVocab() { | ||
| 78 | + return bpeVocab; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + public static class Builder { | ||
| 82 | + private OnlineParaformerModelConfig paraformer = OnlineParaformerModelConfig.builder().build(); | ||
| 83 | + private OnlineTransducerModelConfig transducer = OnlineTransducerModelConfig.builder().build(); | ||
| 84 | + private OnlineZipformer2CtcModelConfig zipformer2Ctc = OnlineZipformer2CtcModelConfig.builder().build(); | ||
| 85 | + private OnlineNeMoCtcModelConfig neMoCtc = OnlineNeMoCtcModelConfig.builder().build(); | ||
| 86 | + private String tokens = ""; | ||
| 87 | + private int numThreads = 1; | ||
| 88 | + private boolean debug = true; | ||
| 89 | + private String provider = "cpu"; | ||
| 90 | + private String modelType = ""; | ||
| 91 | + private String modelingUnit = "cjkchar"; | ||
| 92 | + private String bpeVocab = ""; | ||
| 93 | + | ||
| 94 | + public OnlineModelConfig build() { | ||
| 95 | + return new OnlineModelConfig(this); | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + public Builder setTransducer(OnlineTransducerModelConfig transducer) { | ||
| 99 | + this.transducer = transducer; | ||
| 100 | + return this; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public Builder setParaformer(OnlineParaformerModelConfig paraformer) { | ||
| 104 | + this.paraformer = paraformer; | ||
| 105 | + return this; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + public Builder setZipformer2Ctc(OnlineZipformer2CtcModelConfig zipformer2Ctc) { | ||
| 109 | + this.zipformer2Ctc = zipformer2Ctc; | ||
| 110 | + return this; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + public Builder setNeMoCtc(OnlineNeMoCtcModelConfig neMoCtc) { | ||
| 114 | + this.neMoCtc = neMoCtc; | ||
| 115 | + return this; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + public Builder setTokens(String tokens) { | ||
| 119 | + this.tokens = tokens; | ||
| 120 | + return this; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + public Builder setNumThreads(int numThreads) { | ||
| 124 | + this.numThreads = numThreads; | ||
| 125 | + return this; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + public Builder setDebug(boolean debug) { | ||
| 129 | + this.debug = debug; | ||
| 130 | + return this; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + public Builder setProvider(String provider) { | ||
| 134 | + this.provider = provider; | ||
| 135 | + return this; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + public Builder setModelType(String modelType) { | ||
| 139 | + this.modelType = modelType; | ||
| 140 | + return this; | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + public Builder setModelingUnit(String modelingUnit) { | ||
| 144 | + this.modelingUnit = modelingUnit; | ||
| 145 | + return this; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + public Builder setBpeVocab(String bpeVocab) { | ||
| 149 | + this.bpeVocab = bpeVocab; | ||
| 150 | + return this; | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | +} |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineParaformerModelConfig { | ||
| 7 | - private final String encoder; | ||
| 8 | - private final String decoder; | ||
| 9 | - | ||
| 10 | - private OnlineParaformerModelConfig(Builder builder) { | ||
| 11 | - this.encoder = builder.encoder; | ||
| 12 | - this.decoder = builder.decoder; | ||
| 13 | - } | ||
| 14 | - | ||
| 15 | - public static Builder builder() { | ||
| 16 | - return new Builder(); | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | - public String getEncoder() { | ||
| 20 | - return encoder; | ||
| 21 | - } | ||
| 22 | - | ||
| 23 | - public String getDecoder() { | ||
| 24 | - return decoder; | ||
| 25 | - } | ||
| 26 | - | ||
| 27 | - public static class Builder { | ||
| 28 | - private String encoder = ""; | ||
| 29 | - private String decoder = ""; | ||
| 30 | - | ||
| 31 | - public OnlineParaformerModelConfig build() { | ||
| 32 | - return new OnlineParaformerModelConfig(this); | ||
| 33 | - } | ||
| 34 | - | ||
| 35 | - public Builder setEncoder(String encoder) { | ||
| 36 | - this.encoder = encoder; | ||
| 37 | - return this; | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - public Builder setDecoder(String decoder) { | ||
| 41 | - this.decoder = decoder; | ||
| 42 | - return this; | ||
| 43 | - } | ||
| 44 | - } | ||
| 45 | -} | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineParaformerModelConfig { | ||
| 7 | + private final String encoder; | ||
| 8 | + private final String decoder; | ||
| 9 | + | ||
| 10 | + private OnlineParaformerModelConfig(Builder builder) { | ||
| 11 | + this.encoder = builder.encoder; | ||
| 12 | + this.decoder = builder.decoder; | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + public static Builder builder() { | ||
| 16 | + return new Builder(); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public String getEncoder() { | ||
| 20 | + return encoder; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public String getDecoder() { | ||
| 24 | + return decoder; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public static class Builder { | ||
| 28 | + private String encoder = ""; | ||
| 29 | + private String decoder = ""; | ||
| 30 | + | ||
| 31 | + public OnlineParaformerModelConfig build() { | ||
| 32 | + return new OnlineParaformerModelConfig(this); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public Builder setEncoder(String encoder) { | ||
| 36 | + this.encoder = encoder; | ||
| 37 | + return this; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public Builder setDecoder(String decoder) { | ||
| 41 | + this.decoder = decoder; | ||
| 42 | + return this; | ||
| 43 | + } | ||
| 44 | + } | ||
| 45 | +} |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineRecognizer { | ||
| 7 | - private long ptr = 0; | ||
| 8 | - | ||
| 9 | - public OnlineRecognizer(OnlineRecognizerConfig config) { | ||
| 10 | - LibraryLoader.maybeLoad(); | ||
| 11 | - ptr = newFromFile(config); | ||
| 12 | - } | ||
| 13 | - | ||
| 14 | - public void decode(OnlineStream s) { | ||
| 15 | - decode(ptr, s.getPtr()); | ||
| 16 | - } | ||
| 17 | - | ||
| 18 | - public void decode(OnlineStream[] ss) { | ||
| 19 | - long[] streamPtrs = new long[ss.length]; | ||
| 20 | - for (int i = 0; i < ss.length; ++i) { | ||
| 21 | - streamPtrs[i] = ss[i].getPtr(); | ||
| 22 | - } | ||
| 23 | - decodeStreams(ptr, streamPtrs); | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public boolean isReady(OnlineStream s) { | ||
| 27 | - return isReady(ptr, s.getPtr()); | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - public boolean isEndpoint(OnlineStream s) { | ||
| 31 | - return isEndpoint(ptr, s.getPtr()); | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - public void reset(OnlineStream s) { | ||
| 35 | - reset(ptr, s.getPtr()); | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - public OnlineStream createStream() { | ||
| 39 | - long p = createStream(ptr, ""); | ||
| 40 | - return new OnlineStream(p); | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - @Override | ||
| 44 | - protected void finalize() throws Throwable { | ||
| 45 | - release(); | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - // You'd better call it manually if it is not used anymore | ||
| 49 | - public void release() { | ||
| 50 | - if (this.ptr == 0) { | ||
| 51 | - return; | ||
| 52 | - } | ||
| 53 | - delete(this.ptr); | ||
| 54 | - this.ptr = 0; | ||
| 55 | - } | ||
| 56 | - | ||
| 57 | - public OnlineRecognizerResult getResult(OnlineStream s) { | ||
| 58 | - Object[] arr = getResult(ptr, s.getPtr()); | ||
| 59 | - String text = (String) arr[0]; | ||
| 60 | - String[] tokens = (String[]) arr[1]; | ||
| 61 | - float[] timestamps = (float[]) arr[2]; | ||
| 62 | - return new OnlineRecognizerResult(text, tokens, timestamps); | ||
| 63 | - } | ||
| 64 | - | ||
| 65 | - | ||
| 66 | - private native void delete(long ptr); | ||
| 67 | - | ||
| 68 | - private native long newFromFile(OnlineRecognizerConfig config); | ||
| 69 | - | ||
| 70 | - private native long createStream(long ptr, String hotwords); | ||
| 71 | - | ||
| 72 | - private native void reset(long ptr, long streamPtr); | ||
| 73 | - | ||
| 74 | - private native void decode(long ptr, long streamPtr); | ||
| 75 | - | ||
| 76 | - private native void decodeStreams(long ptr, long[] streamPtrs); | ||
| 77 | - | ||
| 78 | - private native boolean isEndpoint(long ptr, long streamPtr); | ||
| 79 | - | ||
| 80 | - private native boolean isReady(long ptr, long streamPtr); | ||
| 81 | - | ||
| 82 | - private native Object[] getResult(long ptr, long streamPtr); | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineRecognizer { | ||
| 7 | + private long ptr = 0; | ||
| 8 | + | ||
| 9 | + public OnlineRecognizer(OnlineRecognizerConfig config) { | ||
| 10 | + LibraryLoader.maybeLoad(); | ||
| 11 | + ptr = newFromFile(config); | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + public void decode(OnlineStream s) { | ||
| 15 | + decode(ptr, s.getPtr()); | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public void decode(OnlineStream[] ss) { | ||
| 19 | + if (ss == null || ss.length == 0) { | ||
| 20 | + throw new IllegalArgumentException("Stream array must be non-empty"); | ||
| 21 | + } | ||
| 22 | + long[] streamPtrs = new long[ss.length]; | ||
| 23 | + for (int i = 0; i < ss.length; ++i) { | ||
| 24 | + streamPtrs[i] = ss[i].getPtr(); | ||
| 25 | + } | ||
| 26 | + decodeStreams(ptr, streamPtrs); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + public boolean isReady(OnlineStream s) { | ||
| 30 | + return isReady(ptr, s.getPtr()); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public boolean isEndpoint(OnlineStream s) { | ||
| 34 | + return isEndpoint(ptr, s.getPtr()); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public void reset(OnlineStream s) { | ||
| 38 | + reset(ptr, s.getPtr()); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public OnlineStream createStream() { | ||
| 42 | + long p = createStream(ptr, ""); | ||
| 43 | + return new OnlineStream(p); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + @Override | ||
| 47 | + protected void finalize() throws Throwable { | ||
| 48 | + release(); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + // You'd better call it manually if it is not used anymore | ||
| 52 | + protected void close() { | ||
| 53 | + if (this.ptr == 0) { | ||
| 54 | + return; | ||
| 55 | + } | ||
| 56 | + delete(this.ptr); | ||
| 57 | + this.ptr = 0; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + public void release() { | ||
| 61 | + this.close(); | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + public OnlineRecognizerResult getResult(OnlineStream s) { | ||
| 65 | + Object[] arr = getResult(ptr, s.getPtr()); | ||
| 66 | + String text = (String) arr[0]; | ||
| 67 | + String[] tokens = (String[]) arr[1]; | ||
| 68 | + float[] timestamps = (float[]) arr[2]; | ||
| 69 | + return new OnlineRecognizerResult(text, tokens, timestamps); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + | ||
| 73 | + private native void delete(long ptr); | ||
| 74 | + | ||
| 75 | + private native long newFromFile(OnlineRecognizerConfig config); | ||
| 76 | + | ||
| 77 | + private native long createStream(long ptr, String hotwords); | ||
| 78 | + | ||
| 79 | + private native void reset(long ptr, long streamPtr); | ||
| 80 | + | ||
| 81 | + private native void decode(long ptr, long streamPtr); | ||
| 82 | + | ||
| 83 | + private native void decodeStreams(long ptr, long[] streamPtrs); | ||
| 84 | + | ||
| 85 | + private native boolean isEndpoint(long ptr, long streamPtr); | ||
| 86 | + | ||
| 87 | + private native boolean isReady(long ptr, long streamPtr); | ||
| 88 | + | ||
| 89 | + private native Object[] getResult(long ptr, long streamPtr); | ||
| 83 | } | 90 | } |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineRecognizerConfig { | ||
| 7 | - private final FeatureConfig featConfig; | ||
| 8 | - private final OnlineModelConfig modelConfig; | ||
| 9 | - private final OnlineLMConfig lmConfig; | ||
| 10 | - | ||
| 11 | - private final OnlineCtcFstDecoderConfig ctcFstDecoderConfig; | ||
| 12 | - private final EndpointConfig endpointConfig; | ||
| 13 | - private final HomophoneReplacerConfig hr; | ||
| 14 | - private final boolean enableEndpoint; | ||
| 15 | - private final String decodingMethod; | ||
| 16 | - private final int maxActivePaths; | ||
| 17 | - private final String hotwordsFile; | ||
| 18 | - private final float hotwordsScore; | ||
| 19 | - private final String ruleFsts; | ||
| 20 | - private final String ruleFars; | ||
| 21 | - private final float blankPenalty; | ||
| 22 | - | ||
| 23 | - private OnlineRecognizerConfig(Builder builder) { | ||
| 24 | - this.featConfig = builder.featConfig; | ||
| 25 | - this.modelConfig = builder.modelConfig; | ||
| 26 | - this.lmConfig = builder.lmConfig; | ||
| 27 | - this.ctcFstDecoderConfig = builder.ctcFstDecoderConfig; | ||
| 28 | - this.endpointConfig = builder.endpointConfig; | ||
| 29 | - this.hr = builder.hr; | ||
| 30 | - this.enableEndpoint = builder.enableEndpoint; | ||
| 31 | - this.decodingMethod = builder.decodingMethod; | ||
| 32 | - this.maxActivePaths = builder.maxActivePaths; | ||
| 33 | - this.hotwordsFile = builder.hotwordsFile; | ||
| 34 | - this.hotwordsScore = builder.hotwordsScore; | ||
| 35 | - this.ruleFsts = builder.ruleFsts; | ||
| 36 | - this.ruleFars = builder.ruleFars; | ||
| 37 | - this.blankPenalty = builder.blankPenalty; | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - public static Builder builder() { | ||
| 41 | - return new Builder(); | ||
| 42 | - } | ||
| 43 | - | ||
| 44 | - public OnlineModelConfig getModelConfig() { | ||
| 45 | - return modelConfig; | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - public static class Builder { | ||
| 49 | - private FeatureConfig featConfig = FeatureConfig.builder().build(); | ||
| 50 | - private OnlineModelConfig modelConfig = OnlineModelConfig.builder().build(); | ||
| 51 | - private OnlineLMConfig lmConfig = OnlineLMConfig.builder().build(); | ||
| 52 | - private OnlineCtcFstDecoderConfig ctcFstDecoderConfig = OnlineCtcFstDecoderConfig.builder().build(); | ||
| 53 | - private EndpointConfig endpointConfig = EndpointConfig.builder().build(); | ||
| 54 | - private HomophoneReplacerConfig hr = HomophoneReplacerConfig.builder().build(); | ||
| 55 | - private boolean enableEndpoint = true; | ||
| 56 | - private String decodingMethod = "greedy_search"; | ||
| 57 | - private int maxActivePaths = 4; | ||
| 58 | - private String hotwordsFile = ""; | ||
| 59 | - private float hotwordsScore = 1.5f; | ||
| 60 | - private String ruleFsts = ""; | ||
| 61 | - private String ruleFars = ""; | ||
| 62 | - private float blankPenalty = 0.0f; | ||
| 63 | - | ||
| 64 | - public OnlineRecognizerConfig build() { | ||
| 65 | - return new OnlineRecognizerConfig(this); | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - public Builder setFeatureConfig(FeatureConfig featConfig) { | ||
| 69 | - this.featConfig = featConfig; | ||
| 70 | - return this; | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - public Builder setOnlineModelConfig(OnlineModelConfig modelConfig) { | ||
| 74 | - this.modelConfig = modelConfig; | ||
| 75 | - return this; | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - public Builder setOnlineLMConfig(OnlineLMConfig lmConfig) { | ||
| 79 | - this.lmConfig = lmConfig; | ||
| 80 | - return this; | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | - public Builder setCtcFstDecoderConfig(OnlineCtcFstDecoderConfig ctcFstDecoderConfig) { | ||
| 84 | - this.ctcFstDecoderConfig = ctcFstDecoderConfig; | ||
| 85 | - return this; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - public Builder setEndpointConfig(EndpointConfig endpointConfig) { | ||
| 89 | - this.endpointConfig = endpointConfig; | ||
| 90 | - return this; | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - public Builder setHr(HomophoneReplacerConfig hr) { | ||
| 94 | - this.hr = hr; | ||
| 95 | - return this; | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - public Builder setEnableEndpoint(boolean enableEndpoint) { | ||
| 99 | - this.enableEndpoint = enableEndpoint; | ||
| 100 | - return this; | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - public Builder setDecodingMethod(String decodingMethod) { | ||
| 104 | - this.decodingMethod = decodingMethod; | ||
| 105 | - return this; | ||
| 106 | - } | ||
| 107 | - | ||
| 108 | - public Builder setMaxActivePaths(int maxActivePaths) { | ||
| 109 | - this.maxActivePaths = maxActivePaths; | ||
| 110 | - return this; | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - public Builder setHotwordsFile(String hotwordsFile) { | ||
| 114 | - this.hotwordsFile = hotwordsFile; | ||
| 115 | - return this; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - public Builder setHotwordsScore(float hotwordsScore) { | ||
| 119 | - this.hotwordsScore = hotwordsScore; | ||
| 120 | - return this; | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - public Builder setRuleFsts(String ruleFsts) { | ||
| 124 | - this.ruleFsts = ruleFsts; | ||
| 125 | - return this; | ||
| 126 | - } | ||
| 127 | - | ||
| 128 | - public Builder setRuleFars(String ruleFars) { | ||
| 129 | - this.ruleFars = ruleFars; | ||
| 130 | - return this; | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - public Builder setBlankPenalty(float blankPenalty) { | ||
| 134 | - this.blankPenalty = blankPenalty; | ||
| 135 | - return this; | ||
| 136 | - } | ||
| 137 | - } | ||
| 138 | -} | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineRecognizerConfig { | ||
| 7 | + private final FeatureConfig featConfig; | ||
| 8 | + private final OnlineModelConfig modelConfig; | ||
| 9 | + private final OnlineLMConfig lmConfig; | ||
| 10 | + | ||
| 11 | + private final OnlineCtcFstDecoderConfig ctcFstDecoderConfig; | ||
| 12 | + private final EndpointConfig endpointConfig; | ||
| 13 | + private final HomophoneReplacerConfig hr; | ||
| 14 | + private final boolean enableEndpoint; | ||
| 15 | + private final String decodingMethod; | ||
| 16 | + private final int maxActivePaths; | ||
| 17 | + private final String hotwordsFile; | ||
| 18 | + private final float hotwordsScore; | ||
| 19 | + private final String ruleFsts; | ||
| 20 | + private final String ruleFars; | ||
| 21 | + private final float blankPenalty; | ||
| 22 | + | ||
| 23 | + private OnlineRecognizerConfig(Builder builder) { | ||
| 24 | + this.featConfig = builder.featConfig; | ||
| 25 | + this.modelConfig = builder.modelConfig; | ||
| 26 | + this.lmConfig = builder.lmConfig; | ||
| 27 | + this.ctcFstDecoderConfig = builder.ctcFstDecoderConfig; | ||
| 28 | + this.endpointConfig = builder.endpointConfig; | ||
| 29 | + this.hr = builder.hr; | ||
| 30 | + this.enableEndpoint = builder.enableEndpoint; | ||
| 31 | + this.decodingMethod = builder.decodingMethod; | ||
| 32 | + this.maxActivePaths = builder.maxActivePaths; | ||
| 33 | + this.hotwordsFile = builder.hotwordsFile; | ||
| 34 | + this.hotwordsScore = builder.hotwordsScore; | ||
| 35 | + this.ruleFsts = builder.ruleFsts; | ||
| 36 | + this.ruleFars = builder.ruleFars; | ||
| 37 | + this.blankPenalty = builder.blankPenalty; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + public static Builder builder() { | ||
| 41 | + return new Builder(); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + public OnlineModelConfig getModelConfig() { | ||
| 45 | + return modelConfig; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + public static class Builder { | ||
| 49 | + private FeatureConfig featConfig = FeatureConfig.builder().build(); | ||
| 50 | + private OnlineModelConfig modelConfig = OnlineModelConfig.builder().build(); | ||
| 51 | + private OnlineLMConfig lmConfig = OnlineLMConfig.builder().build(); | ||
| 52 | + private OnlineCtcFstDecoderConfig ctcFstDecoderConfig = OnlineCtcFstDecoderConfig.builder().build(); | ||
| 53 | + private EndpointConfig endpointConfig = EndpointConfig.builder().build(); | ||
| 54 | + private HomophoneReplacerConfig hr = HomophoneReplacerConfig.builder().build(); | ||
| 55 | + private boolean enableEndpoint = true; | ||
| 56 | + private String decodingMethod = "greedy_search"; | ||
| 57 | + private int maxActivePaths = 4; | ||
| 58 | + private String hotwordsFile = ""; | ||
| 59 | + private float hotwordsScore = 1.5f; | ||
| 60 | + private String ruleFsts = ""; | ||
| 61 | + private String ruleFars = ""; | ||
| 62 | + private float blankPenalty = 0.0f; | ||
| 63 | + | ||
| 64 | + public OnlineRecognizerConfig build() { | ||
| 65 | + return new OnlineRecognizerConfig(this); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public Builder setFeatureConfig(FeatureConfig featConfig) { | ||
| 69 | + this.featConfig = featConfig; | ||
| 70 | + return this; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + public Builder setOnlineModelConfig(OnlineModelConfig modelConfig) { | ||
| 74 | + this.modelConfig = modelConfig; | ||
| 75 | + return this; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + public Builder setOnlineLMConfig(OnlineLMConfig lmConfig) { | ||
| 79 | + this.lmConfig = lmConfig; | ||
| 80 | + return this; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + public Builder setCtcFstDecoderConfig(OnlineCtcFstDecoderConfig ctcFstDecoderConfig) { | ||
| 84 | + this.ctcFstDecoderConfig = ctcFstDecoderConfig; | ||
| 85 | + return this; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + public Builder setEndpointConfig(EndpointConfig endpointConfig) { | ||
| 89 | + this.endpointConfig = endpointConfig; | ||
| 90 | + return this; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + public Builder setHr(HomophoneReplacerConfig hr) { | ||
| 94 | + this.hr = hr; | ||
| 95 | + return this; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + public Builder setEnableEndpoint(boolean enableEndpoint) { | ||
| 99 | + this.enableEndpoint = enableEndpoint; | ||
| 100 | + return this; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public Builder setDecodingMethod(String decodingMethod) { | ||
| 104 | + this.decodingMethod = decodingMethod; | ||
| 105 | + return this; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + public Builder setMaxActivePaths(int maxActivePaths) { | ||
| 109 | + this.maxActivePaths = maxActivePaths; | ||
| 110 | + return this; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + public Builder setHotwordsFile(String hotwordsFile) { | ||
| 114 | + this.hotwordsFile = hotwordsFile; | ||
| 115 | + return this; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + public Builder setHotwordsScore(float hotwordsScore) { | ||
| 119 | + this.hotwordsScore = hotwordsScore; | ||
| 120 | + return this; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + public Builder setRuleFsts(String ruleFsts) { | ||
| 124 | + this.ruleFsts = ruleFsts; | ||
| 125 | + return this; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + public Builder setRuleFars(String ruleFars) { | ||
| 129 | + this.ruleFars = ruleFars; | ||
| 130 | + return this; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + public Builder setBlankPenalty(float blankPenalty) { | ||
| 134 | + this.blankPenalty = blankPenalty; | ||
| 135 | + return this; | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | +} |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineStream { | ||
| 7 | - private long ptr = 0; | ||
| 8 | - | ||
| 9 | - public OnlineStream() { | ||
| 10 | - LibraryLoader.maybeLoad(); | ||
| 11 | - this.ptr = 0; | ||
| 12 | - } | ||
| 13 | - | ||
| 14 | - public OnlineStream(long ptr) { | ||
| 15 | - this.ptr = ptr; | ||
| 16 | - } | ||
| 17 | - | ||
| 18 | - public long getPtr() { | ||
| 19 | - return ptr; | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - public void setPtr(long ptr) { | ||
| 23 | - this.ptr = ptr; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public void acceptWaveform(float[] samples, int sampleRate) { | ||
| 27 | - acceptWaveform(this.ptr, samples, sampleRate); | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | - public void inputFinished() { | ||
| 31 | - inputFinished(this.ptr); | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - public void release() { | ||
| 35 | - // stream object must be release after used | ||
| 36 | - if (this.ptr == 0) { | ||
| 37 | - return; | ||
| 38 | - } | ||
| 39 | - delete(this.ptr); | ||
| 40 | - this.ptr = 0; | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - @Override | ||
| 44 | - protected void finalize() throws Throwable { | ||
| 45 | - release(); | ||
| 46 | - super.finalize(); | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - private native void acceptWaveform(long ptr, float[] samples, int sampleRate); | ||
| 50 | - | ||
| 51 | - private native void inputFinished(long ptr); | ||
| 52 | - | ||
| 53 | - private native void delete(long ptr); | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineStream { | ||
| 7 | + private long ptr = 0; | ||
| 8 | + | ||
| 9 | + public OnlineStream() { | ||
| 10 | + LibraryLoader.maybeLoad(); | ||
| 11 | + this.ptr = 0; | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + public OnlineStream(long ptr) { | ||
| 15 | + this.ptr = ptr; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public long getPtr() { | ||
| 19 | + return ptr; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public void setPtr(long ptr) { | ||
| 23 | + this.ptr = ptr; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public void acceptWaveform(float[] samples, int sampleRate) { | ||
| 27 | + acceptWaveform(this.ptr, samples, sampleRate); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public void inputFinished() { | ||
| 31 | + inputFinished(this.ptr); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public void release() { | ||
| 35 | + close(); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public void close() { | ||
| 39 | + // stream object must be release after used | ||
| 40 | + if (this.ptr == 0) { | ||
| 41 | + return; | ||
| 42 | + } | ||
| 43 | + delete(this.ptr); | ||
| 44 | + this.ptr = 0; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + protected void finalize() throws Throwable { | ||
| 49 | + close(); | ||
| 50 | + super.finalize(); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + private native void acceptWaveform(long ptr, float[] samples, int sampleRate); | ||
| 54 | + | ||
| 55 | + private native void inputFinished(long ptr); | ||
| 56 | + | ||
| 57 | + private native void delete(long ptr); | ||
| 54 | } | 58 | } |
| 1 | -// Copyright 2022-2023 by zhaoming | ||
| 2 | -// Copyright 2024 Xiaomi Corporation | ||
| 3 | - | ||
| 4 | -package com.k2fsa.sherpa.onnx; | ||
| 5 | - | ||
| 6 | -public class OnlineTransducerModelConfig { | ||
| 7 | - private final String encoder; | ||
| 8 | - private final String decoder; | ||
| 9 | - private final String joiner; | ||
| 10 | - | ||
| 11 | - private OnlineTransducerModelConfig(Builder builder) { | ||
| 12 | - this.encoder = builder.encoder; | ||
| 13 | - this.decoder = builder.decoder; | ||
| 14 | - this.joiner = builder.joiner; | ||
| 15 | - } | ||
| 16 | - | ||
| 17 | - public static Builder builder() { | ||
| 18 | - return new Builder(); | ||
| 19 | - } | ||
| 20 | - | ||
| 21 | - public String getEncoder() { | ||
| 22 | - return encoder; | ||
| 23 | - } | ||
| 24 | - | ||
| 25 | - public String getDecoder() { | ||
| 26 | - return decoder; | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | - public String getJoiner() { | ||
| 30 | - return joiner; | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public static class Builder { | ||
| 34 | - private String encoder = ""; | ||
| 35 | - private String decoder = ""; | ||
| 36 | - private String joiner = ""; | ||
| 37 | - | ||
| 38 | - public OnlineTransducerModelConfig build() { | ||
| 39 | - return new OnlineTransducerModelConfig(this); | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - public Builder setEncoder(String encoder) { | ||
| 43 | - this.encoder = encoder; | ||
| 44 | - return this; | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - public Builder setDecoder(String decoder) { | ||
| 48 | - this.decoder = decoder; | ||
| 49 | - return this; | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - public Builder setJoiner(String joiner) { | ||
| 53 | - this.joiner = joiner; | ||
| 54 | - return this; | ||
| 55 | - } | ||
| 56 | - } | ||
| 57 | -} | 1 | +// Copyright 2022-2023 by zhaoming |
| 2 | +// Copyright 2024 Xiaomi Corporation | ||
| 3 | + | ||
| 4 | +package com.k2fsa.sherpa.onnx; | ||
| 5 | + | ||
| 6 | +public class OnlineTransducerModelConfig { | ||
| 7 | + private final String encoder; | ||
| 8 | + private final String decoder; | ||
| 9 | + private final String joiner; | ||
| 10 | + | ||
| 11 | + private OnlineTransducerModelConfig(Builder builder) { | ||
| 12 | + this.encoder = builder.encoder; | ||
| 13 | + this.decoder = builder.decoder; | ||
| 14 | + this.joiner = builder.joiner; | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + public static Builder builder() { | ||
| 18 | + return new Builder(); | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + public String getEncoder() { | ||
| 22 | + return encoder; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public String getDecoder() { | ||
| 26 | + return decoder; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + public String getJoiner() { | ||
| 30 | + return joiner; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public static class Builder { | ||
| 34 | + private String encoder = ""; | ||
| 35 | + private String decoder = ""; | ||
| 36 | + private String joiner = ""; | ||
| 37 | + | ||
| 38 | + public OnlineTransducerModelConfig build() { | ||
| 39 | + return new OnlineTransducerModelConfig(this); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public Builder setEncoder(String encoder) { | ||
| 43 | + this.encoder = encoder; | ||
| 44 | + return this; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + public Builder setDecoder(String decoder) { | ||
| 48 | + this.decoder = decoder; | ||
| 49 | + return this; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public Builder setJoiner(String joiner) { | ||
| 53 | + this.joiner = joiner; | ||
| 54 | + return this; | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | +} |
| 1 | +package com.k2fsa.sherpa.onnx.utils; | ||
| 2 | + | ||
| 3 | +import java.io.File; | ||
| 4 | +import java.io.IOException; | ||
| 5 | +import java.io.InputStream; | ||
| 6 | +import java.nio.file.Files; | ||
| 7 | +import java.nio.file.StandardCopyOption; | ||
| 8 | +import java.util.Locale; | ||
| 9 | + | ||
| 10 | +import com.k2fsa.sherpa.onnx.core.Core; | ||
| 11 | + | ||
| 12 | +public class LibraryUtils { | ||
| 13 | + // System property to override native library path | ||
| 14 | + private static final String NATIVE_PATH_PROP = "sherpa_onnx.native.path"; | ||
| 15 | + | ||
| 16 | + public static void load() { | ||
| 17 | + String libFileName = System.mapLibraryName(Core.NATIVE_LIBRARY_NAME); | ||
| 18 | + | ||
| 19 | + // 1. Try loading from external directory if provided | ||
| 20 | + String nativePath = System.getProperty(NATIVE_PATH_PROP); | ||
| 21 | + if (nativePath != null) { | ||
| 22 | + File nativeDir = new File(nativePath); | ||
| 23 | + File libInDir = new File(nativeDir, libFileName); | ||
| 24 | + if (nativeDir.isDirectory() && libInDir.exists()) { | ||
| 25 | + System.out.println("Loading native lib from external directory: " + libInDir.getAbsolutePath()); | ||
| 26 | + System.load(libInDir.getAbsolutePath()); | ||
| 27 | + return; | ||
| 28 | + } | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + // 2. Fallback to extracting and loading from the JAR | ||
| 32 | + File libFile = init(libFileName); | ||
| 33 | + System.out.println("Loading native lib from: " + libFile.getAbsolutePath()); | ||
| 34 | + System.load(libFile.getAbsolutePath()); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + /* Computes and initializes OS_ARCH_STR (such as linux-x64) */ | ||
| 38 | + private static String initOsArch() { | ||
| 39 | + String detectedOS = null; | ||
| 40 | + String os = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH); | ||
| 41 | + if (os.contains("mac") || os.contains("darwin")) { | ||
| 42 | + detectedOS = "osx"; | ||
| 43 | + } else if (os.contains("win")) { | ||
| 44 | + detectedOS = "win"; | ||
| 45 | + } else if (os.contains("nux")) { | ||
| 46 | + detectedOS = "linux"; | ||
| 47 | + } else { | ||
| 48 | + throw new IllegalStateException("Unsupported os:" + os); | ||
| 49 | + } | ||
| 50 | + String detectedArch = null; | ||
| 51 | + String arch = System.getProperty("os.arch", "generic").toLowerCase(Locale.ENGLISH); | ||
| 52 | + if (arch.startsWith("amd64") || arch.startsWith("x86_64")) { | ||
| 53 | + detectedArch = "x64"; | ||
| 54 | + } else if (arch.startsWith("x86")) { | ||
| 55 | + // 32-bit x86 is not supported by the Java API | ||
| 56 | + detectedArch = "x86"; | ||
| 57 | + } else if (arch.startsWith("aarch64")) { | ||
| 58 | + detectedArch = "aarch64"; | ||
| 59 | + } else { | ||
| 60 | + throw new IllegalStateException("Unsupported arch:" + arch); | ||
| 61 | + } | ||
| 62 | + return detectedOS + '-' + detectedArch; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + private static File init(String libFileName) { | ||
| 66 | + String osName = System.getProperty("os.name").toLowerCase(); | ||
| 67 | + String osArch = System.getProperty("os.arch").toLowerCase(); | ||
| 68 | + String userHome = System.getProperty("user.home"); | ||
| 69 | + System.out.printf("Detected OS=%s, ARCH=%s, HOME=%s%n", osName, osArch, userHome); | ||
| 70 | + | ||
| 71 | + String archName = initOsArch(); | ||
| 72 | + | ||
| 73 | + // Prepare destination directory under ~/lib/<archName>/ | ||
| 74 | + String dstDir = userHome + File.separator + "lib" + File.separator + archName; | ||
| 75 | + File libFile = new File(dstDir, libFileName); | ||
| 76 | + File parentDir = libFile.getParentFile(); | ||
| 77 | + if (!parentDir.exists() && !parentDir.mkdirs()) { | ||
| 78 | + throw new RuntimeException("Unable to create directory: " + parentDir); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + // Extract the native library from JAR | ||
| 82 | + extractResource("/native/" + archName + "/" + libFileName, libFile); | ||
| 83 | + return libFile; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + /** | ||
| 87 | + * Copies a resource file from the jar to the specified destination. | ||
| 88 | + * | ||
| 89 | + * @param resourcePath The resource path inside the jar, e.g.: | ||
| 90 | + * /native/linux_x64/libonnxruntime.so | ||
| 91 | + * @param destination The destination file on disk | ||
| 92 | + */ | ||
| 93 | + private static void extractResource(String resourcePath, File destination) { | ||
| 94 | + try (InputStream in = LibraryUtils.class.getResourceAsStream(resourcePath)) { | ||
| 95 | + if (in == null) { | ||
| 96 | + throw new RuntimeException("Resource not found: " + resourcePath); | ||
| 97 | + } | ||
| 98 | + Files.copy(in, destination.toPath(), StandardCopyOption.REPLACE_EXISTING); | ||
| 99 | + } catch (IOException e) { | ||
| 100 | + throw new RuntimeException("Failed to extract resource " + resourcePath + " to " + destination.getAbsolutePath(), | ||
| 101 | + e); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | +} |
| 1 | +please downlaod file and put in folder | ||
| 2 | +[donwload link](https://huggingface.co/csukuangfj/sherpa-onnx-libs/tree/main/jni) | ||
| 3 | + | ||
| 4 | +- sherpa-onnx-v1.12.7-linux-aarch64-jni.tar.bz2 | ||
| 5 | +- sherpa-onnx-v1.12.7-linux-x64-jni.tar.bz2 | ||
| 6 | +- sherpa-onnx-v1.12.7-osx-arm64-jni.tar.bz2 | ||
| 7 | +- sherpa-onnx-v1.12.7-osx-x86_64-jni.tar.bz2 | ||
| 8 | +- sherpa-onnx-v1.12.7-win-x64-jni.tar.bz2 | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +- linux_arm64 | ||
| 12 | +- linux_x64 | ||
| 13 | +- darwin_arm64 | ||
| 14 | +- darwin_x64 | ||
| 15 | +- windows_x64 | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +add to src/main/resources | ||
| 19 | + | ||
| 20 | +``` | ||
| 21 | +. | ||
| 22 | +├── native | ||
| 23 | +│ ├── linux-aarch64 | ||
| 24 | +│ │ ├── libsherpa-onnx-jni.so | ||
| 25 | +│ ├── linux-x64 | ||
| 26 | +│ │ ├── libsherpa-onnx-jni.so | ||
| 27 | +│ ├── osx-aarch64 | ||
| 28 | +│ │ ├── libsherpa-onnx-jni.dylib | ||
| 29 | +│ ├── osx-x64 | ||
| 30 | +│ │ ├── libsherpa-onnx-jni.dylib | ||
| 31 | +│ ├── win-x64 | ||
| 32 | +│ │ ├── sherpa-onnx-jni.dll | ||
| 33 | +``` | ||
| 34 | + |
-
请 注册 或 登录 后发表评论