add java wrapper suppport (#117)
This commit is contained in:
101
.clang-format
101
.clang-format
@@ -7,3 +7,104 @@ Standard: Cpp11
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Right
|
||||
---
|
||||
Language: Java
|
||||
JavaImportGroups: [ 'java', 'javax', 'javafx', 'org', 'io', 'com', 'de.gsi' ]
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortLambdasOnASingleLine: None
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: true
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- forever # avoids { wrapped to next line
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeCategories:
|
||||
- Regex: '^<Q.*'
|
||||
Priority: 200
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
|
||||
MacroBlockBegin: ""
|
||||
MacroBlockEnd: ""
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 150
|
||||
PenaltyBreakBeforeFirstCallParameter: 300
|
||||
PenaltyBreakComment: 500
|
||||
PenaltyBreakFirstLessLess: 400
|
||||
PenaltyBreakString: 600
|
||||
PenaltyExcessCharacter: 50
|
||||
PenaltyReturnTypeOnItsOwnLine: 300
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++17
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
61
java-api-examples/Makefile
Executable file
61
java-api-examples/Makefile
Executable file
@@ -0,0 +1,61 @@
|
||||
|
||||
ENTRY_POINT = ./
|
||||
|
||||
LIB_SRC_DIR := ../sherpa-onnx/java-api/src/com/k2fsa/sherpa/onnx
|
||||
|
||||
LIB_FILES = \
|
||||
$(LIB_SRC_DIR)/EndpointRule.java \
|
||||
$(LIB_SRC_DIR)/EndpointConfig.java \
|
||||
$(LIB_SRC_DIR)/FeatureConfig.java \
|
||||
$(LIB_SRC_DIR)/OnlineTransducerModelConfig.java \
|
||||
$(LIB_SRC_DIR)/OnlineRecognizerConfig.java \
|
||||
$(LIB_SRC_DIR)/OnlineStream.java \
|
||||
$(LIB_SRC_DIR)/OnlineRecognizer.java \
|
||||
|
||||
LIB_BUILD_DIR = ./lib
|
||||
|
||||
|
||||
EXAMPLE_FILE = DecodeFile.java
|
||||
|
||||
JAVAC = javac
|
||||
|
||||
BUILD_DIR = build
|
||||
|
||||
|
||||
RUNJFLAGS = -Dfile.encoding=utf-8
|
||||
|
||||
|
||||
vpath %.class $(BUILD_DIR)
|
||||
vpath %.java src
|
||||
|
||||
|
||||
buildexample:
|
||||
$(JAVAC) -cp lib/sherpaonnx.jar -d $(BUILD_DIR) -encoding UTF-8 src/$(EXAMPLE_FILE)
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
.PHONY: clean run
|
||||
|
||||
clean:
|
||||
rm -frv $(BUILD_DIR)/*
|
||||
rm -frv $(LIB_BUILD_DIR)/*
|
||||
mkdir -p $(BUILD_DIR)
|
||||
mkdir -p ./lib
|
||||
|
||||
|
||||
run:
|
||||
|
||||
java -cp ./lib/sherpaonnx.jar:build $(RUNJFLAGS) DecodeFile
|
||||
|
||||
|
||||
buildlib: $(LIB_FILES:.java=.class)
|
||||
|
||||
|
||||
%.class: %.java
|
||||
|
||||
$(JAVAC) -cp $(BUILD_DIR) -d $(BUILD_DIR) -encoding UTF-8 $<
|
||||
|
||||
packjar:
|
||||
jar cvfe lib/sherpaonnx.jar . -C $(BUILD_DIR) .
|
||||
|
||||
all: clean buildlib packjar buildexample run
|
||||
88
java-api-examples/README.md
Executable file
88
java-api-examples/README.md
Executable file
@@ -0,0 +1,88 @@
|
||||
|
||||
0.Introduction
|
||||
---
|
||||
Java wrapper `com.k2fsa.sherpaonnx.OnlineRecognizer` for `sherpa-onnx`. Java is a cross-platform language; you can build jni .so lib according to your system, and then use the same java api for all your platform.
|
||||
``` xml
|
||||
Depend on:
|
||||
Openjdk 1.8
|
||||
```
|
||||
---
|
||||
1.Compile libsherpa-onnx-jni.so
|
||||
---
|
||||
Compile sherpa-onnx/jni/jni.cc according to your system.
|
||||
Example for Ubuntu 18.04 LTS, Openjdk 1.8.0_362:
|
||||
``` xml
|
||||
git clone https://github.com/k2-fsa/sherpa-onnx
|
||||
cd sherpa-onnx
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DSHERPA_ONNX_ENABLE_JNI=ON ..
|
||||
make -j6
|
||||
```
|
||||
---
|
||||
2.Download asr model files
|
||||
---
|
||||
[click here for more detail](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html)
|
||||
---
|
||||
3.Config model config.cfg
|
||||
---
|
||||
``` xml
|
||||
#model config
|
||||
sample_rate=16000
|
||||
feature_dim=80
|
||||
rule1_min_trailing_silence=2.4
|
||||
rule2_min_trailing_silence=1.2
|
||||
rule3_min_utterance_length=20
|
||||
encoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx
|
||||
decoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx
|
||||
joiner=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx
|
||||
tokens=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt
|
||||
num_threads=4
|
||||
enable_endpoint_detection=false
|
||||
decoding_method=greedy_search
|
||||
max_active_paths=4
|
||||
```
|
||||
---
|
||||
4.A simple java example
|
||||
---
|
||||
refer to [java_api_example](https://github.com/k2-fsa/sherpa-onnx/blob/master/java-api-examples/src/DecodeFile.java) for more detail.
|
||||
``` java
|
||||
import com.k2fsa.sherpa.onnx.OnlineRecognizer;
|
||||
import com.k2fsa.sherpa.onnx.OnlineStream;
|
||||
String cfgpath=appdir+"/modelconfig.cfg";
|
||||
OnlineRecognizer.setSoPath(soPath); //set so lib path
|
||||
|
||||
OnlineRecognizer rcgOjb = new OnlineRecognizer(); //create a recognizer
|
||||
rcgOjb = new OnlineRecognizer(cfgFile); //set model config file
|
||||
CreateStream streamObj=rcgOjb.CreateStream(); //create a stream for read wav data
|
||||
float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file
|
||||
streamObj.acceptWaveform(buffer); // feed stream with data
|
||||
streamObj.inputFinished(); // tell engine you done with all data
|
||||
OnlineStream ssObj[] = new OnlineStream[1];
|
||||
while (rcgOjb.isReady(streamObj)) { // engine is ready for unprocessed data
|
||||
ssObj[0] = streamObj;
|
||||
rcgOjb.decodeStreams(ssObj); // decode for multiple stream
|
||||
// rcgOjb.DecodeStream(streamObj); // decode for single stream
|
||||
}
|
||||
|
||||
String recText = "simple:" + rcgOjb.getResult(streamObj) + "\n";
|
||||
byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8);
|
||||
System.out.println(new String(utf8Data));
|
||||
rcgOjb.reSet(streamObj);
|
||||
rcgOjb.releaseStream(streamObj); // release stream
|
||||
rcgOjb.release(); // release recognizer
|
||||
|
||||
|
||||
```
|
||||
---
|
||||
5.Makefile
|
||||
---
|
||||
package jar and run app example
|
||||
package path: /sherpa-onnx/java-api-examples/lib/sherpaonnx.jar
|
||||
``` bash
|
||||
cd sherpa-onnx/java-api-examples
|
||||
make all
|
||||
|
||||
```
|
||||
|
||||
|
||||
14
java-api-examples/modelconfig.cfg
Executable file
14
java-api-examples/modelconfig.cfg
Executable file
@@ -0,0 +1,14 @@
|
||||
#model config
|
||||
sample_rate=16000
|
||||
feature_dim=80
|
||||
rule1_min_trailing_silence=2.4
|
||||
rule2_min_trailing_silence=1.2
|
||||
rule3_min_utterance_length=20
|
||||
encoder=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx
|
||||
decoder=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx
|
||||
joiner=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx
|
||||
tokens=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt
|
||||
num_threads=4
|
||||
enable_endpoint_detection=false
|
||||
decoding_method=modified_beam_search
|
||||
max_active_paths=4
|
||||
174
java-api-examples/src/DecodeFile.java
Normal file
174
java-api-examples/src/DecodeFile.java
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
/*
|
||||
Config modelconfig.cfg
|
||||
sample_rate=16000
|
||||
feature_dim=80
|
||||
rule1_min_trailing_silence=2.4
|
||||
rule2_min_trailing_silence=1.2
|
||||
rule3_min_utterance_length=20
|
||||
encoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx
|
||||
decoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx
|
||||
joiner=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx
|
||||
tokens=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt
|
||||
num_threads=4
|
||||
enable_endpoint_detection=false
|
||||
decoding_method=greedy_search
|
||||
max_active_paths=4
|
||||
*/
|
||||
|
||||
import com.k2fsa.sherpa.onnx.OnlineRecognizer;
|
||||
import com.k2fsa.sherpa.onnx.OnlineStream;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class DecodeFile {
|
||||
OnlineRecognizer rcgOjb;
|
||||
OnlineStream streamObj;
|
||||
String wavfilename;
|
||||
|
||||
public DecodeFile(String fileName) {
|
||||
wavfilename = fileName;
|
||||
}
|
||||
|
||||
public void initModelWithPara() {
|
||||
try {
|
||||
String modelDir =
|
||||
"/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20";
|
||||
String encoder = modelDir + "/encoder-epoch-99-avg-1.onnx";
|
||||
String decoder = modelDir + "/decoder-epoch-99-avg-1.onnx";
|
||||
String joiner = modelDir + "/joiner-epoch-99-avg-1.onnx";
|
||||
String tokens = modelDir + "/tokens.txt";
|
||||
int numThreads = 4;
|
||||
int sampleRate = 16000;
|
||||
int featureDim = 80;
|
||||
boolean enableEndpointDetection = false;
|
||||
float rule1MinTrailingSilence = 2.4F;
|
||||
float rule2MinTrailingSilence = 1.2F;
|
||||
float rule3MinUtteranceLength = 20F;
|
||||
String decodingMethod = "greedy_search";
|
||||
int maxActivePaths = 4;
|
||||
|
||||
rcgOjb =
|
||||
new OnlineRecognizer(
|
||||
tokens,
|
||||
encoder,
|
||||
decoder,
|
||||
joiner,
|
||||
numThreads,
|
||||
sampleRate,
|
||||
featureDim,
|
||||
enableEndpointDetection,
|
||||
rule1MinTrailingSilence,
|
||||
rule2MinTrailingSilence,
|
||||
rule3MinUtteranceLength,
|
||||
decodingMethod,
|
||||
maxActivePaths);
|
||||
streamObj = rcgOjb.createStream();
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void initModelWithCfg(String cfgFile) {
|
||||
try {
|
||||
// you should set setCfgPath() before running this
|
||||
rcgOjb = new OnlineRecognizer(cfgFile);
|
||||
streamObj = rcgOjb.createStream();
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void simpleExample() {
|
||||
try {
|
||||
float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file
|
||||
streamObj.acceptWaveform(buffer); // feed stream with data
|
||||
streamObj.inputFinished(); // tell engine you done with all data
|
||||
OnlineStream ssObj[] = new OnlineStream[1];
|
||||
while (rcgOjb.isReady(streamObj)) { // engine is ready for unprocessed data
|
||||
ssObj[0] = streamObj;
|
||||
rcgOjb.decodeStreams(ssObj); // decode for multiple stream
|
||||
// rcgOjb.DecodeStream(streamObj); // decode for single stream
|
||||
}
|
||||
|
||||
String recText = "simple:" + rcgOjb.getResult(streamObj) + "\n";
|
||||
byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8);
|
||||
System.out.println(new String(utf8Data));
|
||||
rcgOjb.reSet(streamObj);
|
||||
rcgOjb.releaseStream(streamObj); // release stream
|
||||
rcgOjb.release(); // release recognizer
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void streamExample() {
|
||||
try {
|
||||
float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file
|
||||
float[] chunk = new float[1600]; // //each time read 1600(0.1s) data
|
||||
int chunkIndex = 0;
|
||||
for (int i = 0; i < buffer.length; i++) // total wav length loop
|
||||
{
|
||||
chunk[chunkIndex] = buffer[i];
|
||||
chunkIndex++;
|
||||
if (chunkIndex >= 1600 || i == (buffer.length - 1)) {
|
||||
chunkIndex = 0;
|
||||
streamObj.acceptWaveform(chunk); // feed chunk
|
||||
if (rcgOjb.isReady(streamObj)) {
|
||||
rcgOjb.decodeStream(streamObj);
|
||||
}
|
||||
String testDate = rcgOjb.getResult(streamObj);
|
||||
byte[] utf8Data = testDate.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
if (utf8Data.length > 0) {
|
||||
System.out.println(Float.valueOf((float) i / 16000) + ":" + new String(utf8Data));
|
||||
}
|
||||
}
|
||||
}
|
||||
streamObj.inputFinished();
|
||||
while (rcgOjb.isReady(streamObj)) {
|
||||
rcgOjb.decodeStream(streamObj);
|
||||
}
|
||||
|
||||
String recText = "stream:" + rcgOjb.getResult(streamObj) + "\n";
|
||||
byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8);
|
||||
System.out.println(new String(utf8Data));
|
||||
rcgOjb.reSet(streamObj);
|
||||
rcgOjb.releaseStream(streamObj); // release stream
|
||||
rcgOjb.release(); // release recognizer
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
String appDir = System.getProperty("user.dir");
|
||||
System.out.println("appdir=" + appDir);
|
||||
String fileName = appDir + "/test.wav";
|
||||
String cfgPath = appDir + "/modelconfig.cfg";
|
||||
String soPath = appDir + "/../build/lib/libsherpa-onnx-jni.so";
|
||||
OnlineRecognizer.setSoPath(soPath);
|
||||
DecodeFile rcgDemo = new DecodeFile(fileName);
|
||||
|
||||
// ***************** */
|
||||
rcgDemo.initModelWithCfg(cfgPath);
|
||||
rcgDemo.streamExample();
|
||||
// **************** */
|
||||
rcgDemo.initModelWithCfg(cfgPath);
|
||||
rcgDemo.simpleExample();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
java-api-examples/test.wav
Normal file
BIN
java-api-examples/test.wav
Normal file
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
public class EndpointConfig {
|
||||
private final EndpointRule rule1;
|
||||
private final EndpointRule rule2;
|
||||
private final EndpointRule rule3;
|
||||
|
||||
public EndpointConfig(EndpointRule rule1, EndpointRule rule2, EndpointRule rule3) {
|
||||
this.rule1 = rule1;
|
||||
this.rule2 = rule2;
|
||||
this.rule3 = rule3;
|
||||
}
|
||||
|
||||
public EndpointRule getRule1() {
|
||||
return rule1;
|
||||
}
|
||||
|
||||
public EndpointRule getRule2() {
|
||||
return rule2;
|
||||
}
|
||||
|
||||
public EndpointRule getRule3() {
|
||||
return rule3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
public class EndpointRule {
|
||||
private final boolean mustContainNonSilence;
|
||||
private final float minTrailingSilence;
|
||||
private final float minUtteranceLength;
|
||||
|
||||
public EndpointRule(
|
||||
boolean mustContainNonSilence, float minTrailingSilence, float minUtteranceLength) {
|
||||
this.mustContainNonSilence = mustContainNonSilence;
|
||||
this.minTrailingSilence = minTrailingSilence;
|
||||
this.minUtteranceLength = minUtteranceLength;
|
||||
}
|
||||
|
||||
public float getMinTrailingSilence() {
|
||||
return minTrailingSilence;
|
||||
}
|
||||
|
||||
public float getMinUtteranceLength() {
|
||||
return minUtteranceLength;
|
||||
}
|
||||
|
||||
public boolean getMustContainNonSilence() {
|
||||
return mustContainNonSilence;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
public class FeatureConfig {
|
||||
private final int sampleRate;
|
||||
private final int featureDim;
|
||||
|
||||
public FeatureConfig(int sampleRate, int featureDim) {
|
||||
this.sampleRate = sampleRate;
|
||||
this.featureDim = featureDim;
|
||||
}
|
||||
|
||||
public int getSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
public int getFeatureDim() {
|
||||
return featureDim;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
* // the online recognizer for sherpa-onnx, it can load config from a file
|
||||
* // or by argument
|
||||
*/
|
||||
/*
|
||||
usage example:
|
||||
|
||||
String cfgpath=appdir+"/modelconfig.cfg";
|
||||
OnlineRecognizer.setSoPath(soPath); //set so lib path
|
||||
|
||||
OnlineRecognizer rcgOjb = new OnlineRecognizer(); //create a recognizer
|
||||
rcgOjb = new OnlineRecognizer(cfgFile); //set model config file
|
||||
CreateStream streamObj=rcgOjb.CreateStream(); //create a stream for read wav data
|
||||
float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file
|
||||
streamObj.acceptWaveform(buffer); // feed stream with data
|
||||
streamObj.inputFinished(); // tell engine you done with all data
|
||||
OnlineStream ssObj[] = new OnlineStream[1];
|
||||
while (rcgOjb.isReady(streamObj)) { // engine is ready for unprocessed data
|
||||
ssObj[0] = streamObj;
|
||||
rcgOjb.decodeStreams(ssObj); // decode for multiple stream
|
||||
// rcgOjb.DecodeStream(streamObj); // decode for single stream
|
||||
}
|
||||
|
||||
String recText = "simple:" + rcgOjb.getResult(streamObj) + "\n";
|
||||
byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8);
|
||||
System.out.println(new String(utf8Data));
|
||||
rcgOjb.reSet(streamObj);
|
||||
rcgOjb.releaseStream(streamObj); // release stream
|
||||
rcgOjb.release(); // release recognizer
|
||||
|
||||
*/
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class OnlineRecognizer {
|
||||
private long ptr = 0; // this is the asr engine ptrss
|
||||
|
||||
private int sampleRate = 16000;
|
||||
// load config file for OnlineRecognizer
|
||||
public OnlineRecognizer(String modelCfgPath) {
|
||||
Map<String, String> proMap = this.readProperties(modelCfgPath);
|
||||
try {
|
||||
int sampleRate = Integer.parseInt(proMap.get("sample_rate").trim());
|
||||
this.sampleRate = sampleRate;
|
||||
EndpointRule rule1 =
|
||||
new EndpointRule(
|
||||
false, Float.parseFloat(proMap.get("rule1_min_trailing_silence").trim()), 0.0F);
|
||||
EndpointRule rule2 =
|
||||
new EndpointRule(
|
||||
true, Float.parseFloat(proMap.get("rule2_min_trailing_silence").trim()), 0.0F);
|
||||
EndpointRule rule3 =
|
||||
new EndpointRule(
|
||||
false, 0.0F, Float.parseFloat(proMap.get("rule3_min_utterance_length").trim()));
|
||||
EndpointConfig endCfg = new EndpointConfig(rule1, rule2, rule3);
|
||||
OnlineTransducerModelConfig modelCfg =
|
||||
new OnlineTransducerModelConfig(
|
||||
proMap.get("encoder").trim(),
|
||||
proMap.get("decoder").trim(),
|
||||
proMap.get("joiner").trim(),
|
||||
proMap.get("tokens").trim(),
|
||||
Integer.parseInt(proMap.get("num_threads").trim()),
|
||||
false);
|
||||
FeatureConfig featConfig =
|
||||
new FeatureConfig(sampleRate, Integer.parseInt(proMap.get("feature_dim").trim()));
|
||||
OnlineRecognizerConfig rcgCfg =
|
||||
new OnlineRecognizerConfig(
|
||||
featConfig,
|
||||
modelCfg,
|
||||
endCfg,
|
||||
Boolean.parseBoolean(proMap.get("enable_endpoint_detection").trim()),
|
||||
proMap.get("decoding_method").trim(),
|
||||
Integer.parseInt(proMap.get("max_active_paths").trim()));
|
||||
// create a new Recognizer, first parameter kept for android asset_manager ANDROID_API__ >= 9
|
||||
this.ptr = createOnlineRecognizer(new Object(), rcgCfg);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
// use for android asset_manager ANDROID_API__ >= 9
|
||||
public OnlineRecognizer(Object assetManager, String modelCfgPath) {
|
||||
Map<String, String> proMap = this.readProperties(modelCfgPath);
|
||||
try {
|
||||
int sampleRate = Integer.parseInt(proMap.get("sample_rate").trim());
|
||||
this.sampleRate = sampleRate;
|
||||
EndpointRule rule1 =
|
||||
new EndpointRule(
|
||||
false, Float.parseFloat(proMap.get("rule1_min_trailing_silence").trim()), 0.0F);
|
||||
EndpointRule rule2 =
|
||||
new EndpointRule(
|
||||
true, Float.parseFloat(proMap.get("rule2_min_trailing_silence").trim()), 0.0F);
|
||||
EndpointRule rule3 =
|
||||
new EndpointRule(
|
||||
false, 0.0F, Float.parseFloat(proMap.get("rule3_min_utterance_length").trim()));
|
||||
EndpointConfig endCfg = new EndpointConfig(rule1, rule2, rule3);
|
||||
OnlineTransducerModelConfig modelCfg =
|
||||
new OnlineTransducerModelConfig(
|
||||
proMap.get("encoder").trim(),
|
||||
proMap.get("decoder").trim(),
|
||||
proMap.get("joiner").trim(),
|
||||
proMap.get("tokens").trim(),
|
||||
Integer.parseInt(proMap.get("num_threads").trim()),
|
||||
false);
|
||||
FeatureConfig featConfig =
|
||||
new FeatureConfig(sampleRate, Integer.parseInt(proMap.get("feature_dim").trim()));
|
||||
OnlineRecognizerConfig rcgCfg =
|
||||
new OnlineRecognizerConfig(
|
||||
featConfig,
|
||||
modelCfg,
|
||||
endCfg,
|
||||
Boolean.parseBoolean(proMap.get("enable_endpoint_detection").trim()),
|
||||
proMap.get("decoding_method").trim(),
|
||||
Integer.parseInt(proMap.get("max_active_paths").trim()));
|
||||
// create a new Recognizer, first parameter kept for android asset_manager ANDROID_API__ >= 9
|
||||
this.ptr = createOnlineRecognizer(assetManager, rcgCfg);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
// set onlineRecognizer by parameter
|
||||
public OnlineRecognizer(
|
||||
String tokens,
|
||||
String encoder,
|
||||
String decoder,
|
||||
String joiner,
|
||||
int numThreads,
|
||||
int sampleRate,
|
||||
int featureDim,
|
||||
boolean enableEndpointDetection,
|
||||
float rule1MinTrailingSilence,
|
||||
float rule2MinTrailingSilence,
|
||||
float rule3MinUtteranceLength,
|
||||
String decodingMethod,
|
||||
int maxActivePaths) {
|
||||
this.sampleRate = sampleRate;
|
||||
EndpointRule rule1 = new EndpointRule(false, rule1MinTrailingSilence, 0.0F);
|
||||
EndpointRule rule2 = new EndpointRule(true, rule2MinTrailingSilence, 0.0F);
|
||||
EndpointRule rule3 = new EndpointRule(false, 0.0F, rule3MinUtteranceLength);
|
||||
EndpointConfig endCfg = new EndpointConfig(rule1, rule2, rule3);
|
||||
OnlineTransducerModelConfig modelCfg =
|
||||
new OnlineTransducerModelConfig(encoder, decoder, joiner, tokens, numThreads, false);
|
||||
FeatureConfig featConfig = new FeatureConfig(sampleRate, featureDim);
|
||||
OnlineRecognizerConfig rcgCfg =
|
||||
new OnlineRecognizerConfig(
|
||||
featConfig,
|
||||
modelCfg,
|
||||
endCfg,
|
||||
enableEndpointDetection,
|
||||
decodingMethod,
|
||||
maxActivePaths);
|
||||
// create a new Recognizer, first parameter kept for android asset_manager ANDROID_API__ >= 9
|
||||
this.ptr = createOnlineRecognizer(new Object(), rcgCfg);
|
||||
}
|
||||
|
||||
private Map<String, String> readProperties(String modelCfgPath) {
|
||||
// read and parse config file
|
||||
Properties props = new Properties();
|
||||
Map<String, String> proMap = new HashMap<>();
|
||||
try {
|
||||
File file = new File(modelCfgPath);
|
||||
if (!file.exists()) {
|
||||
System.out.println("model cfg file not exists!");
|
||||
System.exit(0);
|
||||
}
|
||||
InputStream in = new BufferedInputStream(new FileInputStream(modelCfgPath));
|
||||
props.load(in);
|
||||
Enumeration en = props.propertyNames();
|
||||
while (en.hasMoreElements()) {
|
||||
String key = (String) en.nextElement();
|
||||
String Property = props.getProperty(key);
|
||||
proMap.put(key, Property);
|
||||
// System.out.println(key+"="+Property);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return proMap;
|
||||
}
|
||||
|
||||
public void decodeStream(OnlineStream s) throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
long streamPtr = s.getPtr();
|
||||
if (streamPtr == 0) throw new Exception("null exception for stream ptr");
|
||||
// when feeded samples to engine, call DecodeStream to let it process
|
||||
decodeStream(this.ptr, streamPtr);
|
||||
}
|
||||
|
||||
public void decodeStreams(OnlineStream[] ssOjb) throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
// decode for multiple streams
|
||||
long[] ss = new long[ssOjb.length];
|
||||
for (int i = 0; i < ssOjb.length; i++) {
|
||||
ss[i] = ssOjb[i].getPtr();
|
||||
if (ss[i] == 0) throw new Exception("null exception for stream ptr");
|
||||
}
|
||||
decodeStreams(this.ptr, ss);
|
||||
}
|
||||
|
||||
public boolean isReady(OnlineStream s) throws Exception {
|
||||
// whether the engine is ready for decode
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
long streamPtr = s.getPtr();
|
||||
if (streamPtr == 0) throw new Exception("null exception for stream ptr");
|
||||
return isReady(this.ptr, streamPtr);
|
||||
}
|
||||
|
||||
public String getResult(OnlineStream s) throws Exception {
|
||||
// get text from the engine
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
long streamPtr = s.getPtr();
|
||||
if (streamPtr == 0) throw new Exception("null exception for stream ptr");
|
||||
return getResult(this.ptr, streamPtr);
|
||||
}
|
||||
|
||||
public boolean isEndpoint(OnlineStream s) throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
long streamPtr = s.getPtr();
|
||||
if (streamPtr == 0) throw new Exception("null exception for stream ptr");
|
||||
return isEndpoint(this.ptr, streamPtr);
|
||||
}
|
||||
|
||||
public void reSet(OnlineStream s) throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
long streamPtr = s.getPtr();
|
||||
if (streamPtr == 0) throw new Exception("null exception for stream ptr");
|
||||
reSet(this.ptr, streamPtr);
|
||||
}
|
||||
|
||||
public OnlineStream createStream() throws Exception {
|
||||
// create one stream for data to feed in
|
||||
if (this.ptr == 0) throw new Exception("null exception for recognizer ptr");
|
||||
long streamPtr = createStream(this.ptr);
|
||||
OnlineStream stream = new OnlineStream(streamPtr, this.sampleRate);
|
||||
return stream;
|
||||
}
|
||||
|
||||
public float[] readWavFile(String fileName) {
|
||||
// read data from the filename
|
||||
Object[] wavdata = readWave(fileName);
|
||||
Object data = wavdata[0]; // data[0] is float data, data[1] sample rate
|
||||
|
||||
float[] floatData = (float[]) data;
|
||||
|
||||
return floatData;
|
||||
}
|
||||
|
||||
// load the libsherpa-onnx-jni.so lib
|
||||
public static void loadSoLib(String soPath) {
|
||||
// load libsherpa-onnx-jni.so lib from the path
|
||||
|
||||
System.out.println("so lib path=" + soPath + "\n");
|
||||
System.load(soPath.trim());
|
||||
}
|
||||
|
||||
public static void setSoPath(String soPath) {
|
||||
OnlineRecognizer.loadSoLib(soPath);
|
||||
OnlineStream.loadSoLib(soPath);
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
release();
|
||||
}
|
||||
|
||||
// recognizer release, you'd better call it manually if not use anymore
|
||||
public void release() {
|
||||
if (this.ptr == 0) return;
|
||||
deleteOnlineRecognizer(this.ptr);
|
||||
this.ptr = 0;
|
||||
}
|
||||
|
||||
// stream release, you'd better call it manually if not use anymore
|
||||
public void releaseStream(OnlineStream s) {
|
||||
s.release();
|
||||
}
|
||||
// JNI interface libsherpa-onnx-jni.so
|
||||
|
||||
private native Object[] readWave(String fileName);
|
||||
|
||||
private native String getResult(long ptr, long streamPtr);
|
||||
|
||||
private native void decodeStream(long ptr, long streamPtr);
|
||||
|
||||
private native void decodeStreams(long ptr, long[] ssPtr);
|
||||
|
||||
private native boolean isReady(long ptr, long streamPtr);
|
||||
|
||||
// first parameter keep for android asset_manager ANDROID_API__ >= 9
|
||||
private native long createOnlineRecognizer(Object asset, OnlineRecognizerConfig config);
|
||||
|
||||
private native long createStream(long ptr);
|
||||
|
||||
private native void deleteOnlineRecognizer(long ptr);
|
||||
|
||||
private native boolean isEndpoint(long ptr, long streamPtr);
|
||||
|
||||
private native void reSet(long ptr, long streamPtr);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
public class OnlineRecognizerConfig {
|
||||
private final FeatureConfig featConfig;
|
||||
private final OnlineTransducerModelConfig modelConfig;
|
||||
private final EndpointConfig endpointConfig;
|
||||
private final boolean enableEndpoint;
|
||||
private final String decodingMethod;
|
||||
private final int maxActivePaths;
|
||||
|
||||
public OnlineRecognizerConfig(
|
||||
FeatureConfig featConfig,
|
||||
OnlineTransducerModelConfig modelConfig,
|
||||
EndpointConfig endpointConfig,
|
||||
boolean enableEndpoint,
|
||||
String decodingMethod,
|
||||
int maxActivePaths) {
|
||||
this.featConfig = featConfig;
|
||||
this.modelConfig = modelConfig;
|
||||
this.endpointConfig = endpointConfig;
|
||||
this.enableEndpoint = enableEndpoint;
|
||||
this.decodingMethod = decodingMethod;
|
||||
this.maxActivePaths = maxActivePaths;
|
||||
}
|
||||
|
||||
public FeatureConfig getFeatConfig() {
|
||||
return featConfig;
|
||||
}
|
||||
|
||||
public OnlineTransducerModelConfig getModelConfig() {
|
||||
return modelConfig;
|
||||
}
|
||||
|
||||
public EndpointConfig getEndpointConfig() {
|
||||
return endpointConfig;
|
||||
}
|
||||
|
||||
public boolean isEnableEndpoint() {
|
||||
return enableEndpoint;
|
||||
}
|
||||
|
||||
public String getDecodingMethod() {
|
||||
return decodingMethod;
|
||||
}
|
||||
|
||||
public int getMaxActivePaths() {
|
||||
return maxActivePaths;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
// Stream is used for feeding data to the asr engine
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class OnlineStream {
|
||||
private long ptr = 0; // this is the stream ptr
|
||||
|
||||
private int sampleRate = 16000;
|
||||
// assign ptr to this stream in construction
|
||||
public OnlineStream(long ptr, int sampleRate) {
|
||||
this.ptr = ptr;
|
||||
this.sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
public long getPtr() {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
public void acceptWaveform(float[] samples) throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for stream ptr");
|
||||
|
||||
// feed wave data to asr engine
|
||||
acceptWaveform(this.ptr, this.sampleRate, samples);
|
||||
}
|
||||
|
||||
public void inputFinished() {
|
||||
// add some tail padding
|
||||
int padLen = (int) (this.sampleRate * 0.3); // 0.3 seconds at 16 kHz sample rate
|
||||
float tailPaddings[] = new float[padLen]; // default value is 0
|
||||
acceptWaveform(this.ptr, this.sampleRate, tailPaddings);
|
||||
|
||||
// tell the engine all data are feeded
|
||||
inputFinished(this.ptr);
|
||||
}
|
||||
|
||||
public static void loadSoLib(String soPath) {
|
||||
// load .so lib from the path
|
||||
System.load(soPath.trim()); // ("sherpa-onnx-jni-java");
|
||||
}
|
||||
|
||||
public void release() {
|
||||
// stream object must be release after used
|
||||
if (this.ptr == 0) return;
|
||||
deleteStream(this.ptr);
|
||||
this.ptr = 0;
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
release();
|
||||
}
|
||||
|
||||
public boolean isLastFrame() throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for stream ptr");
|
||||
return isLastFrame(this.ptr);
|
||||
}
|
||||
|
||||
public void reSet() throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for stream ptr");
|
||||
reSet(this.ptr);
|
||||
}
|
||||
|
||||
public int featureDim() throws Exception {
|
||||
if (this.ptr == 0) throw new Exception("null exception for stream ptr");
|
||||
return featureDim(this.ptr);
|
||||
}
|
||||
|
||||
// JNI interface libsherpa-onnx-jni.so
|
||||
private native void acceptWaveform(long ptr, int sampleRate, float[] samples);
|
||||
|
||||
private native void inputFinished(long ptr);
|
||||
|
||||
private native void deleteStream(long ptr);
|
||||
|
||||
private native int numFramesReady(long ptr);
|
||||
|
||||
private native boolean isLastFrame(long ptr);
|
||||
|
||||
private native void reSet(long ptr);
|
||||
|
||||
private native int featureDim(long ptr);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* // Copyright 2022-2023 by zhaoming
|
||||
*/
|
||||
|
||||
package com.k2fsa.sherpa.onnx;
|
||||
|
||||
public class OnlineTransducerModelConfig {
|
||||
private final String encoder;
|
||||
private final String decoder;
|
||||
private final String joiner;
|
||||
private final String tokens;
|
||||
private final int numThreads;
|
||||
private final boolean debug;
|
||||
|
||||
public OnlineTransducerModelConfig(
|
||||
String encoder, String decoder, String joiner, String tokens, int numThreads, boolean debug) {
|
||||
this.encoder = encoder;
|
||||
this.decoder = decoder;
|
||||
this.joiner = joiner;
|
||||
this.tokens = tokens;
|
||||
this.numThreads = numThreads;
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
public String getEncoder() {
|
||||
return encoder;
|
||||
}
|
||||
|
||||
public String getDecoder() {
|
||||
return decoder;
|
||||
}
|
||||
|
||||
public String getJoiner() {
|
||||
return joiner;
|
||||
}
|
||||
|
||||
public String getTokens() {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public int getNumThreads() {
|
||||
return numThreads;
|
||||
}
|
||||
|
||||
public boolean getDebug() {
|
||||
return debug;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
//
|
||||
// Copyright (c) 2022-2023 Xiaomi Corporation
|
||||
// 2022 Pingfeng Luo
|
||||
// 2023 Zhaoming
|
||||
|
||||
// TODO(fangjun): Add documentation to functions/methods in this file
|
||||
// and also show how to use them with kotlin, possibly with java.
|
||||
@@ -12,7 +13,6 @@
|
||||
|
||||
#include <strstream>
|
||||
#include <utility>
|
||||
|
||||
#if __ANDROID_API__ >= 9
|
||||
#include "android/asset_manager.h"
|
||||
#include "android/asset_manager_jni.h"
|
||||
@@ -207,7 +207,6 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_SherpaOnnx_new(
|
||||
SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr);
|
||||
}
|
||||
#endif
|
||||
|
||||
auto config = sherpa_onnx::GetConfig(env, _config);
|
||||
SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str());
|
||||
auto model = new sherpa_onnx::SherpaOnnx(
|
||||
@@ -301,7 +300,7 @@ Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave(
|
||||
SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_LOGE("Failed to read %s", p_filename);
|
||||
std::vector<char> buffer = sherpa_onnx::ReadFile(mgr, p_filename);
|
||||
|
||||
std::istrstream is(buffer.data(), buffer.size());
|
||||
@@ -332,3 +331,186 @@ Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave(
|
||||
|
||||
return obj_arr;
|
||||
}
|
||||
|
||||
// ******warpper for OnlineRecognizer*******
|
||||
|
||||
// wav reader for java interface
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_readWave(JNIEnv *env,
|
||||
jclass /*cls*/,
|
||||
jstring filename) {
|
||||
auto data = Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave(
|
||||
env, nullptr, nullptr, filename);
|
||||
return data;
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT jlong JNICALL
|
||||
|
||||
Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_createOnlineRecognizer(
|
||||
|
||||
JNIEnv *env, jobject /*obj*/, jobject asset_manager, jobject _config) {
|
||||
#if __ANDROID_API__ >= 9
|
||||
AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager);
|
||||
if (!mgr) {
|
||||
SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr);
|
||||
}
|
||||
#endif
|
||||
sherpa_onnx::OnlineRecognizerConfig config =
|
||||
sherpa_onnx::GetConfig(env, _config);
|
||||
SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str());
|
||||
auto p_recognizer = new sherpa_onnx::OnlineRecognizer(
|
||||
#if __ANDROID_API__ >= 9
|
||||
mgr,
|
||||
#endif
|
||||
config);
|
||||
return (jlong)p_recognizer;
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_deleteOnlineRecognizer(
|
||||
JNIEnv *env, jobject /*obj*/, jlong ptr) {
|
||||
delete reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_createStream(JNIEnv *env,
|
||||
jobject /*obj*/,
|
||||
jlong ptr) {
|
||||
std::unique_ptr<sherpa_onnx::OnlineStream> s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr)->CreateStream();
|
||||
sherpa_onnx::OnlineStream *p_stream = s.release();
|
||||
return reinterpret_cast<jlong>(p_stream);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_isReady(
|
||||
JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineRecognizer *model =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
return model->IsReady(s);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_decodeStream(
|
||||
JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineRecognizer *model =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
model->DecodeStream(s);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_decodeStreams(JNIEnv *env,
|
||||
jobject /*obj*/,
|
||||
jlong ptr,
|
||||
jlongArray ss_ptr,
|
||||
jint stream_size) {
|
||||
sherpa_onnx::OnlineRecognizer *model =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
jlong *p = env->GetLongArrayElements(ss_ptr, nullptr);
|
||||
jsize n = env->GetArrayLength(ss_ptr);
|
||||
std::vector<sherpa_onnx::OnlineStream *> p_ss(n);
|
||||
for (int32_t i = 0; i != n; ++i) {
|
||||
p_ss[i] = reinterpret_cast<sherpa_onnx::OnlineStream *>(p[i]);
|
||||
}
|
||||
|
||||
model->DecodeStreams(p_ss.data(), n);
|
||||
env->ReleaseLongArrayElements(ss_ptr, p, JNI_ABORT);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT jstring JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_getResult(
|
||||
JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineRecognizer *model =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
sherpa_onnx::OnlineRecognizerResult result = model->GetResult(s);
|
||||
return env->NewStringUTF(result.ToString().c_str());
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_isEndpoint(
|
||||
JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineRecognizer *model =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
return model->IsEndpoint(s);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_reSet(
|
||||
JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineRecognizer *model =
|
||||
reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr);
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
model->Reset(s);
|
||||
}
|
||||
|
||||
// *********for OnlineStream *********
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_acceptWaveform(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr, jint sample_rate,
|
||||
jfloatArray waveform) {
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
jfloat *p = env->GetFloatArrayElements(waveform, nullptr);
|
||||
jsize n = env->GetArrayLength(waveform);
|
||||
s->AcceptWaveform(sample_rate, p, n);
|
||||
env->ReleaseFloatArrayElements(waveform, p, JNI_ABORT);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_inputFinished(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
s->InputFinished();
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_deleteStream(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr) {
|
||||
delete reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT jint JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_numFramesReady(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
return s->NumFramesReady();
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_isLastFrame(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr, jint frame) {
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
return s->IsLastFrame(frame);
|
||||
}
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_reSet(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
s->Reset();
|
||||
}
|
||||
|
||||
SHERPA_ONNX_EXTERN_C
|
||||
JNIEXPORT jint JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_featureDim(
|
||||
JNIEnv *env, jobject /*obj*/, jlong s_ptr) {
|
||||
sherpa_onnx::OnlineStream *s =
|
||||
reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr);
|
||||
return s->FeatureDim();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user