正在显示
14 个修改的文件
包含
1196 行增加
和
3 行删除
| @@ -7,3 +7,104 @@ Standard: Cpp11 | @@ -7,3 +7,104 @@ Standard: Cpp11 | ||
| 7 | DerivePointerAlignment: false | 7 | DerivePointerAlignment: false |
| 8 | PointerAlignment: Right | 8 | PointerAlignment: Right |
| 9 | --- | 9 | --- |
| 10 | +Language: Java | ||
| 11 | +JavaImportGroups: [ 'java', 'javax', 'javafx', 'org', 'io', 'com', 'de.gsi' ] | ||
| 12 | +AccessModifierOffset: -4 | ||
| 13 | +AlignAfterOpenBracket: DontAlign | ||
| 14 | +AlignConsecutiveAssignments: false | ||
| 15 | +AlignConsecutiveDeclarations: false | ||
| 16 | +AlignEscapedNewlines: DontAlign | ||
| 17 | +AlignTrailingComments: false | ||
| 18 | +AllowAllParametersOfDeclarationOnNextLine: true | ||
| 19 | +AllowShortLambdasOnASingleLine: None | ||
| 20 | +AllowShortCaseLabelsOnASingleLine: false | ||
| 21 | +AllowShortFunctionsOnASingleLine: None | ||
| 22 | +AllowShortIfStatementsOnASingleLine: Never | ||
| 23 | +AllowShortLoopsOnASingleLine: false | ||
| 24 | +AlwaysBreakAfterReturnType: None | ||
| 25 | +AlwaysBreakBeforeMultilineStrings: false | ||
| 26 | +AlwaysBreakTemplateDeclarations: Yes | ||
| 27 | +BinPackArguments: true | ||
| 28 | +BinPackParameters: true | ||
| 29 | +BraceWrapping: | ||
| 30 | + AfterClass: false | ||
| 31 | + AfterControlStatement: Never | ||
| 32 | + AfterEnum: false | ||
| 33 | + AfterFunction: false | ||
| 34 | + AfterNamespace: false | ||
| 35 | + AfterObjCDeclaration: false | ||
| 36 | + AfterStruct: false | ||
| 37 | + AfterUnion: false | ||
| 38 | + BeforeCatch: false | ||
| 39 | + BeforeElse: false | ||
| 40 | + IndentBraces: false | ||
| 41 | + SplitEmptyFunction: true | ||
| 42 | + SplitEmptyRecord: true | ||
| 43 | + SplitEmptyNamespace: true | ||
| 44 | +BreakBeforeBinaryOperators: All | ||
| 45 | +BreakBeforeBraces: Custom | ||
| 46 | +BreakBeforeInheritanceComma: false | ||
| 47 | +BreakBeforeTernaryOperators: true | ||
| 48 | +BreakConstructorInitializersBeforeComma: false | ||
| 49 | +BreakConstructorInitializers: BeforeComma | ||
| 50 | +BreakAfterJavaFieldAnnotations: true | ||
| 51 | +BreakStringLiterals: true | ||
| 52 | +ColumnLimit: 0 | ||
| 53 | +CommentPragmas: '^ IWYU pragma:' | ||
| 54 | +CompactNamespaces: false | ||
| 55 | +ConstructorInitializerAllOnOneLineOrOnePerLine: false | ||
| 56 | +ConstructorInitializerIndentWidth: 4 | ||
| 57 | +ContinuationIndentWidth: 8 | ||
| 58 | +Cpp11BracedListStyle: false | ||
| 59 | +DerivePointerAlignment: false | ||
| 60 | +DisableFormat: false | ||
| 61 | +ExperimentalAutoDetectBinPacking: false | ||
| 62 | +FixNamespaceComments: true | ||
| 63 | +ForEachMacros: | ||
| 64 | + - forever # avoids { wrapped to next line | ||
| 65 | + - foreach | ||
| 66 | + - Q_FOREACH | ||
| 67 | + - BOOST_FOREACH | ||
| 68 | +IncludeCategories: | ||
| 69 | + - Regex: '^<Q.*' | ||
| 70 | + Priority: 200 | ||
| 71 | +IncludeIsMainRegex: '(Test)?$' | ||
| 72 | +IndentCaseLabels: false | ||
| 73 | +IndentWidth: 4 | ||
| 74 | +IndentWrappedFunctionNames: false | ||
| 75 | +JavaScriptQuotes: Leave | ||
| 76 | +JavaScriptWrapImports: true | ||
| 77 | +KeepEmptyLinesAtTheStartOfBlocks: false | ||
| 78 | +# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between. | ||
| 79 | +MacroBlockBegin: "" | ||
| 80 | +MacroBlockEnd: "" | ||
| 81 | +MaxEmptyLinesToKeep: 1 | ||
| 82 | +NamespaceIndentation: None | ||
| 83 | +ObjCBlockIndentWidth: 4 | ||
| 84 | +ObjCSpaceAfterProperty: false | ||
| 85 | +ObjCSpaceBeforeProtocolList: true | ||
| 86 | +PenaltyBreakAssignment: 150 | ||
| 87 | +PenaltyBreakBeforeFirstCallParameter: 300 | ||
| 88 | +PenaltyBreakComment: 500 | ||
| 89 | +PenaltyBreakFirstLessLess: 400 | ||
| 90 | +PenaltyBreakString: 600 | ||
| 91 | +PenaltyExcessCharacter: 50 | ||
| 92 | +PenaltyReturnTypeOnItsOwnLine: 300 | ||
| 93 | +PointerAlignment: Right | ||
| 94 | +ReflowComments: true | ||
| 95 | +SortIncludes: true | ||
| 96 | +SortUsingDeclarations: true | ||
| 97 | +SpaceAfterCStyleCast: true | ||
| 98 | +SpaceAfterTemplateKeyword: false | ||
| 99 | +SpaceBeforeAssignmentOperators: true | ||
| 100 | +SpaceBeforeParens: ControlStatements | ||
| 101 | +SpaceInEmptyParentheses: false | ||
| 102 | +SpacesBeforeTrailingComments: 1 | ||
| 103 | +SpacesInAngles: false | ||
| 104 | +SpacesInContainerLiterals: false | ||
| 105 | +SpacesInCStyleCastParentheses: false | ||
| 106 | +SpacesInParentheses: false | ||
| 107 | +SpacesInSquareBrackets: false | ||
| 108 | +Standard: c++17 | ||
| 109 | +TabWidth: 4 | ||
| 110 | +UseTab: Never |
java-api-examples/Makefile
0 → 100755
| 1 | + | ||
| 2 | +ENTRY_POINT = ./ | ||
| 3 | + | ||
| 4 | +LIB_SRC_DIR := ../sherpa-onnx/java-api/src/com/k2fsa/sherpa/onnx | ||
| 5 | + | ||
| 6 | +LIB_FILES = \ | ||
| 7 | + $(LIB_SRC_DIR)/EndpointRule.java \ | ||
| 8 | + $(LIB_SRC_DIR)/EndpointConfig.java \ | ||
| 9 | + $(LIB_SRC_DIR)/FeatureConfig.java \ | ||
| 10 | + $(LIB_SRC_DIR)/OnlineTransducerModelConfig.java \ | ||
| 11 | + $(LIB_SRC_DIR)/OnlineRecognizerConfig.java \ | ||
| 12 | + $(LIB_SRC_DIR)/OnlineStream.java \ | ||
| 13 | + $(LIB_SRC_DIR)/OnlineRecognizer.java \ | ||
| 14 | + | ||
| 15 | +LIB_BUILD_DIR = ./lib | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +EXAMPLE_FILE = DecodeFile.java | ||
| 19 | + | ||
| 20 | +JAVAC = javac | ||
| 21 | + | ||
| 22 | +BUILD_DIR = build | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +RUNJFLAGS = -Dfile.encoding=utf-8 | ||
| 26 | + | ||
| 27 | + | ||
| 28 | +vpath %.class $(BUILD_DIR) | ||
| 29 | +vpath %.java src | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +buildexample: | ||
| 33 | + $(JAVAC) -cp lib/sherpaonnx.jar -d $(BUILD_DIR) -encoding UTF-8 src/$(EXAMPLE_FILE) | ||
| 34 | + | ||
| 35 | +rebuild: clean all | ||
| 36 | + | ||
| 37 | +.PHONY: clean run | ||
| 38 | + | ||
| 39 | +clean: | ||
| 40 | + rm -frv $(BUILD_DIR)/* | ||
| 41 | + rm -frv $(LIB_BUILD_DIR)/* | ||
| 42 | + mkdir -p $(BUILD_DIR) | ||
| 43 | + mkdir -p ./lib | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +run: | ||
| 47 | + | ||
| 48 | + java -cp ./lib/sherpaonnx.jar:build $(RUNJFLAGS) DecodeFile | ||
| 49 | + | ||
| 50 | + | ||
| 51 | +buildlib: $(LIB_FILES:.java=.class) | ||
| 52 | + | ||
| 53 | + | ||
| 54 | +%.class: %.java | ||
| 55 | + | ||
| 56 | + $(JAVAC) -cp $(BUILD_DIR) -d $(BUILD_DIR) -encoding UTF-8 $< | ||
| 57 | + | ||
| 58 | +packjar: | ||
| 59 | + jar cvfe lib/sherpaonnx.jar . -C $(BUILD_DIR) . | ||
| 60 | + | ||
| 61 | +all: clean buildlib packjar buildexample run |
java-api-examples/README.md
0 → 100755
| 1 | + | ||
| 2 | +0.Introduction | ||
| 3 | +--- | ||
| 4 | +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. | ||
| 5 | +``` xml | ||
| 6 | +Depend on: | ||
| 7 | + Openjdk 1.8 | ||
| 8 | +``` | ||
| 9 | +--- | ||
| 10 | +1.Compile libsherpa-onnx-jni.so | ||
| 11 | +--- | ||
| 12 | +Compile sherpa-onnx/jni/jni.cc according to your system. | ||
| 13 | +Example for Ubuntu 18.04 LTS, Openjdk 1.8.0_362: | ||
| 14 | +``` xml | ||
| 15 | + git clone https://github.com/k2-fsa/sherpa-onnx | ||
| 16 | + cd sherpa-onnx | ||
| 17 | + mkdir build | ||
| 18 | + cd build | ||
| 19 | + cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DSHERPA_ONNX_ENABLE_JNI=ON .. | ||
| 20 | + make -j6 | ||
| 21 | +``` | ||
| 22 | +--- | ||
| 23 | +2.Download asr model files | ||
| 24 | +--- | ||
| 25 | +[click here for more detail](https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html) | ||
| 26 | +--- | ||
| 27 | +3.Config model config.cfg | ||
| 28 | +--- | ||
| 29 | +``` xml | ||
| 30 | + #model config | ||
| 31 | + sample_rate=16000 | ||
| 32 | + feature_dim=80 | ||
| 33 | + rule1_min_trailing_silence=2.4 | ||
| 34 | + rule2_min_trailing_silence=1.2 | ||
| 35 | + rule3_min_utterance_length=20 | ||
| 36 | + encoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx | ||
| 37 | + decoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx | ||
| 38 | + joiner=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx | ||
| 39 | + tokens=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt | ||
| 40 | + num_threads=4 | ||
| 41 | + enable_endpoint_detection=false | ||
| 42 | + decoding_method=greedy_search | ||
| 43 | + max_active_paths=4 | ||
| 44 | +``` | ||
| 45 | +--- | ||
| 46 | +4.A simple java example | ||
| 47 | +--- | ||
| 48 | +refer to [java_api_example](https://github.com/k2-fsa/sherpa-onnx/blob/master/java-api-examples/src/DecodeFile.java) for more detail. | ||
| 49 | +``` java | ||
| 50 | + import com.k2fsa.sherpa.onnx.OnlineRecognizer; | ||
| 51 | + import com.k2fsa.sherpa.onnx.OnlineStream; | ||
| 52 | + String cfgpath=appdir+"/modelconfig.cfg"; | ||
| 53 | + OnlineRecognizer.setSoPath(soPath); //set so lib path | ||
| 54 | + | ||
| 55 | + OnlineRecognizer rcgOjb = new OnlineRecognizer(); //create a recognizer | ||
| 56 | + rcgOjb = new OnlineRecognizer(cfgFile); //set model config file | ||
| 57 | + CreateStream streamObj=rcgOjb.CreateStream(); //create a stream for read wav data | ||
| 58 | + float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file | ||
| 59 | + streamObj.acceptWaveform(buffer); // feed stream with data | ||
| 60 | + streamObj.inputFinished(); // tell engine you done with all data | ||
| 61 | + OnlineStream ssObj[] = new OnlineStream[1]; | ||
| 62 | + while (rcgOjb.isReady(streamObj)) { // engine is ready for unprocessed data | ||
| 63 | + ssObj[0] = streamObj; | ||
| 64 | + rcgOjb.decodeStreams(ssObj); // decode for multiple stream | ||
| 65 | + // rcgOjb.DecodeStream(streamObj); // decode for single stream | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + String recText = "simple:" + rcgOjb.getResult(streamObj) + "\n"; | ||
| 69 | + byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8); | ||
| 70 | + System.out.println(new String(utf8Data)); | ||
| 71 | + rcgOjb.reSet(streamObj); | ||
| 72 | + rcgOjb.releaseStream(streamObj); // release stream | ||
| 73 | + rcgOjb.release(); // release recognizer | ||
| 74 | + | ||
| 75 | + | ||
| 76 | +``` | ||
| 77 | +--- | ||
| 78 | +5.Makefile | ||
| 79 | +--- | ||
| 80 | +package jar and run app example | ||
| 81 | +package path: /sherpa-onnx/java-api-examples/lib/sherpaonnx.jar | ||
| 82 | +``` bash | ||
| 83 | + cd sherpa-onnx/java-api-examples | ||
| 84 | + make all | ||
| 85 | + | ||
| 86 | + ``` | ||
| 87 | + | ||
| 88 | + |
java-api-examples/modelconfig.cfg
0 → 100755
| 1 | +#model config | ||
| 2 | +sample_rate=16000 | ||
| 3 | +feature_dim=80 | ||
| 4 | +rule1_min_trailing_silence=2.4 | ||
| 5 | +rule2_min_trailing_silence=1.2 | ||
| 6 | +rule3_min_utterance_length=20 | ||
| 7 | +encoder=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx | ||
| 8 | +decoder=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx | ||
| 9 | +joiner=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx | ||
| 10 | +tokens=/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt | ||
| 11 | +num_threads=4 | ||
| 12 | +enable_endpoint_detection=false | ||
| 13 | +decoding_method=modified_beam_search | ||
| 14 | +max_active_paths=4 |
java-api-examples/src/DecodeFile.java
0 → 100644
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | +/* | ||
| 5 | +Config modelconfig.cfg | ||
| 6 | + sample_rate=16000 | ||
| 7 | + feature_dim=80 | ||
| 8 | + rule1_min_trailing_silence=2.4 | ||
| 9 | + rule2_min_trailing_silence=1.2 | ||
| 10 | + rule3_min_utterance_length=20 | ||
| 11 | + encoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx | ||
| 12 | + decoder=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx | ||
| 13 | + joiner=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx | ||
| 14 | + tokens=/sherpa-onnx/build/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt | ||
| 15 | + num_threads=4 | ||
| 16 | + enable_endpoint_detection=false | ||
| 17 | + decoding_method=greedy_search | ||
| 18 | + max_active_paths=4 | ||
| 19 | +*/ | ||
| 20 | + | ||
| 21 | +import com.k2fsa.sherpa.onnx.OnlineRecognizer; | ||
| 22 | +import com.k2fsa.sherpa.onnx.OnlineStream; | ||
| 23 | +import java.io.*; | ||
| 24 | +import java.nio.charset.StandardCharsets; | ||
| 25 | + | ||
| 26 | +public class DecodeFile { | ||
| 27 | + OnlineRecognizer rcgOjb; | ||
| 28 | + OnlineStream streamObj; | ||
| 29 | + String wavfilename; | ||
| 30 | + | ||
| 31 | + public DecodeFile(String fileName) { | ||
| 32 | + wavfilename = fileName; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public void initModelWithPara() { | ||
| 36 | + try { | ||
| 37 | + String modelDir = | ||
| 38 | + "/sherpa-onnx/build_old/bin/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20"; | ||
| 39 | + String encoder = modelDir + "/encoder-epoch-99-avg-1.onnx"; | ||
| 40 | + String decoder = modelDir + "/decoder-epoch-99-avg-1.onnx"; | ||
| 41 | + String joiner = modelDir + "/joiner-epoch-99-avg-1.onnx"; | ||
| 42 | + String tokens = modelDir + "/tokens.txt"; | ||
| 43 | + int numThreads = 4; | ||
| 44 | + int sampleRate = 16000; | ||
| 45 | + int featureDim = 80; | ||
| 46 | + boolean enableEndpointDetection = false; | ||
| 47 | + float rule1MinTrailingSilence = 2.4F; | ||
| 48 | + float rule2MinTrailingSilence = 1.2F; | ||
| 49 | + float rule3MinUtteranceLength = 20F; | ||
| 50 | + String decodingMethod = "greedy_search"; | ||
| 51 | + int maxActivePaths = 4; | ||
| 52 | + | ||
| 53 | + rcgOjb = | ||
| 54 | + new OnlineRecognizer( | ||
| 55 | + tokens, | ||
| 56 | + encoder, | ||
| 57 | + decoder, | ||
| 58 | + joiner, | ||
| 59 | + numThreads, | ||
| 60 | + sampleRate, | ||
| 61 | + featureDim, | ||
| 62 | + enableEndpointDetection, | ||
| 63 | + rule1MinTrailingSilence, | ||
| 64 | + rule2MinTrailingSilence, | ||
| 65 | + rule3MinUtteranceLength, | ||
| 66 | + decodingMethod, | ||
| 67 | + maxActivePaths); | ||
| 68 | + streamObj = rcgOjb.createStream(); | ||
| 69 | + } catch (Exception e) { | ||
| 70 | + System.err.println(e); | ||
| 71 | + e.printStackTrace(); | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public void initModelWithCfg(String cfgFile) { | ||
| 76 | + try { | ||
| 77 | + // you should set setCfgPath() before running this | ||
| 78 | + rcgOjb = new OnlineRecognizer(cfgFile); | ||
| 79 | + streamObj = rcgOjb.createStream(); | ||
| 80 | + } catch (Exception e) { | ||
| 81 | + System.err.println(e); | ||
| 82 | + e.printStackTrace(); | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + public void simpleExample() { | ||
| 87 | + try { | ||
| 88 | + float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file | ||
| 89 | + streamObj.acceptWaveform(buffer); // feed stream with data | ||
| 90 | + streamObj.inputFinished(); // tell engine you done with all data | ||
| 91 | + OnlineStream ssObj[] = new OnlineStream[1]; | ||
| 92 | + while (rcgOjb.isReady(streamObj)) { // engine is ready for unprocessed data | ||
| 93 | + ssObj[0] = streamObj; | ||
| 94 | + rcgOjb.decodeStreams(ssObj); // decode for multiple stream | ||
| 95 | + // rcgOjb.DecodeStream(streamObj); // decode for single stream | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + String recText = "simple:" + rcgOjb.getResult(streamObj) + "\n"; | ||
| 99 | + byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8); | ||
| 100 | + System.out.println(new String(utf8Data)); | ||
| 101 | + rcgOjb.reSet(streamObj); | ||
| 102 | + rcgOjb.releaseStream(streamObj); // release stream | ||
| 103 | + rcgOjb.release(); // release recognizer | ||
| 104 | + | ||
| 105 | + } catch (Exception e) { | ||
| 106 | + System.err.println(e); | ||
| 107 | + e.printStackTrace(); | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + public void streamExample() { | ||
| 112 | + try { | ||
| 113 | + float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file | ||
| 114 | + float[] chunk = new float[1600]; // //each time read 1600(0.1s) data | ||
| 115 | + int chunkIndex = 0; | ||
| 116 | + for (int i = 0; i < buffer.length; i++) // total wav length loop | ||
| 117 | + { | ||
| 118 | + chunk[chunkIndex] = buffer[i]; | ||
| 119 | + chunkIndex++; | ||
| 120 | + if (chunkIndex >= 1600 || i == (buffer.length - 1)) { | ||
| 121 | + chunkIndex = 0; | ||
| 122 | + streamObj.acceptWaveform(chunk); // feed chunk | ||
| 123 | + if (rcgOjb.isReady(streamObj)) { | ||
| 124 | + rcgOjb.decodeStream(streamObj); | ||
| 125 | + } | ||
| 126 | + String testDate = rcgOjb.getResult(streamObj); | ||
| 127 | + byte[] utf8Data = testDate.getBytes(StandardCharsets.UTF_8); | ||
| 128 | + | ||
| 129 | + if (utf8Data.length > 0) { | ||
| 130 | + System.out.println(Float.valueOf((float) i / 16000) + ":" + new String(utf8Data)); | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + streamObj.inputFinished(); | ||
| 135 | + while (rcgOjb.isReady(streamObj)) { | ||
| 136 | + rcgOjb.decodeStream(streamObj); | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + String recText = "stream:" + rcgOjb.getResult(streamObj) + "\n"; | ||
| 140 | + byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8); | ||
| 141 | + System.out.println(new String(utf8Data)); | ||
| 142 | + rcgOjb.reSet(streamObj); | ||
| 143 | + rcgOjb.releaseStream(streamObj); // release stream | ||
| 144 | + rcgOjb.release(); // release recognizer | ||
| 145 | + | ||
| 146 | + } catch (Exception e) { | ||
| 147 | + System.err.println(e); | ||
| 148 | + e.printStackTrace(); | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + public static void main(String[] args) { | ||
| 153 | + try { | ||
| 154 | + String appDir = System.getProperty("user.dir"); | ||
| 155 | + System.out.println("appdir=" + appDir); | ||
| 156 | + String fileName = appDir + "/test.wav"; | ||
| 157 | + String cfgPath = appDir + "/modelconfig.cfg"; | ||
| 158 | + String soPath = appDir + "/../build/lib/libsherpa-onnx-jni.so"; | ||
| 159 | + OnlineRecognizer.setSoPath(soPath); | ||
| 160 | + DecodeFile rcgDemo = new DecodeFile(fileName); | ||
| 161 | + | ||
| 162 | + // ***************** */ | ||
| 163 | + rcgDemo.initModelWithCfg(cfgPath); | ||
| 164 | + rcgDemo.streamExample(); | ||
| 165 | + // **************** */ | ||
| 166 | + rcgDemo.initModelWithCfg(cfgPath); | ||
| 167 | + rcgDemo.simpleExample(); | ||
| 168 | + | ||
| 169 | + } catch (Exception e) { | ||
| 170 | + System.err.println(e); | ||
| 171 | + e.printStackTrace(); | ||
| 172 | + } | ||
| 173 | + } | ||
| 174 | +} |
java-api-examples/test.wav
0 → 100644
不能预览此文件类型
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +package com.k2fsa.sherpa.onnx; | ||
| 6 | + | ||
| 7 | +public class EndpointConfig { | ||
| 8 | + private final EndpointRule rule1; | ||
| 9 | + private final EndpointRule rule2; | ||
| 10 | + private final EndpointRule rule3; | ||
| 11 | + | ||
| 12 | + public EndpointConfig(EndpointRule rule1, EndpointRule rule2, EndpointRule rule3) { | ||
| 13 | + this.rule1 = rule1; | ||
| 14 | + this.rule2 = rule2; | ||
| 15 | + this.rule3 = rule3; | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + public EndpointRule getRule1() { | ||
| 19 | + return rule1; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + public EndpointRule getRule2() { | ||
| 23 | + return rule2; | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + public EndpointRule getRule3() { | ||
| 27 | + return rule3; | ||
| 28 | + } | ||
| 29 | +} |
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +package com.k2fsa.sherpa.onnx; | ||
| 6 | + | ||
| 7 | +public class EndpointRule { | ||
| 8 | + private final boolean mustContainNonSilence; | ||
| 9 | + private final float minTrailingSilence; | ||
| 10 | + private final float minUtteranceLength; | ||
| 11 | + | ||
| 12 | + public EndpointRule( | ||
| 13 | + boolean mustContainNonSilence, float minTrailingSilence, float minUtteranceLength) { | ||
| 14 | + this.mustContainNonSilence = mustContainNonSilence; | ||
| 15 | + this.minTrailingSilence = minTrailingSilence; | ||
| 16 | + this.minUtteranceLength = minUtteranceLength; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public float getMinTrailingSilence() { | ||
| 20 | + return minTrailingSilence; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public float getMinUtteranceLength() { | ||
| 24 | + return minUtteranceLength; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public boolean getMustContainNonSilence() { | ||
| 28 | + return mustContainNonSilence; | ||
| 29 | + } | ||
| 30 | +} |
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +package com.k2fsa.sherpa.onnx; | ||
| 6 | + | ||
| 7 | +public class FeatureConfig { | ||
| 8 | + private final int sampleRate; | ||
| 9 | + private final int featureDim; | ||
| 10 | + | ||
| 11 | + public FeatureConfig(int sampleRate, int featureDim) { | ||
| 12 | + this.sampleRate = sampleRate; | ||
| 13 | + this.featureDim = featureDim; | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public int getSampleRate() { | ||
| 17 | + return sampleRate; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public int getFeatureDim() { | ||
| 21 | + return featureDim; | ||
| 22 | + } | ||
| 23 | +} |
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + * // the online recognizer for sherpa-onnx, it can load config from a file | ||
| 4 | + * // or by argument | ||
| 5 | + */ | ||
| 6 | +/* | ||
| 7 | +usage example: | ||
| 8 | + | ||
| 9 | + String cfgpath=appdir+"/modelconfig.cfg"; | ||
| 10 | + OnlineRecognizer.setSoPath(soPath); //set so lib path | ||
| 11 | + | ||
| 12 | + OnlineRecognizer rcgOjb = new OnlineRecognizer(); //create a recognizer | ||
| 13 | + rcgOjb = new OnlineRecognizer(cfgFile); //set model config file | ||
| 14 | + CreateStream streamObj=rcgOjb.CreateStream(); //create a stream for read wav data | ||
| 15 | + float[] buffer = rcgOjb.readWavFile(wavfilename); // read data from file | ||
| 16 | + streamObj.acceptWaveform(buffer); // feed stream with data | ||
| 17 | + streamObj.inputFinished(); // tell engine you done with all data | ||
| 18 | + OnlineStream ssObj[] = new OnlineStream[1]; | ||
| 19 | + while (rcgOjb.isReady(streamObj)) { // engine is ready for unprocessed data | ||
| 20 | + ssObj[0] = streamObj; | ||
| 21 | + rcgOjb.decodeStreams(ssObj); // decode for multiple stream | ||
| 22 | + // rcgOjb.DecodeStream(streamObj); // decode for single stream | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + String recText = "simple:" + rcgOjb.getResult(streamObj) + "\n"; | ||
| 26 | + byte[] utf8Data = recText.getBytes(StandardCharsets.UTF_8); | ||
| 27 | + System.out.println(new String(utf8Data)); | ||
| 28 | + rcgOjb.reSet(streamObj); | ||
| 29 | + rcgOjb.releaseStream(streamObj); // release stream | ||
| 30 | + rcgOjb.release(); // release recognizer | ||
| 31 | + | ||
| 32 | +*/ | ||
| 33 | +package com.k2fsa.sherpa.onnx; | ||
| 34 | + | ||
| 35 | +import java.io.*; | ||
| 36 | +import java.util.*; | ||
| 37 | + | ||
| 38 | +public class OnlineRecognizer { | ||
| 39 | + private long ptr = 0; // this is the asr engine ptrss | ||
| 40 | + | ||
| 41 | + private int sampleRate = 16000; | ||
| 42 | + // load config file for OnlineRecognizer | ||
| 43 | + public OnlineRecognizer(String modelCfgPath) { | ||
| 44 | + Map<String, String> proMap = this.readProperties(modelCfgPath); | ||
| 45 | + try { | ||
| 46 | + int sampleRate = Integer.parseInt(proMap.get("sample_rate").trim()); | ||
| 47 | + this.sampleRate = sampleRate; | ||
| 48 | + EndpointRule rule1 = | ||
| 49 | + new EndpointRule( | ||
| 50 | + false, Float.parseFloat(proMap.get("rule1_min_trailing_silence").trim()), 0.0F); | ||
| 51 | + EndpointRule rule2 = | ||
| 52 | + new EndpointRule( | ||
| 53 | + true, Float.parseFloat(proMap.get("rule2_min_trailing_silence").trim()), 0.0F); | ||
| 54 | + EndpointRule rule3 = | ||
| 55 | + new EndpointRule( | ||
| 56 | + false, 0.0F, Float.parseFloat(proMap.get("rule3_min_utterance_length").trim())); | ||
| 57 | + EndpointConfig endCfg = new EndpointConfig(rule1, rule2, rule3); | ||
| 58 | + OnlineTransducerModelConfig modelCfg = | ||
| 59 | + new OnlineTransducerModelConfig( | ||
| 60 | + proMap.get("encoder").trim(), | ||
| 61 | + proMap.get("decoder").trim(), | ||
| 62 | + proMap.get("joiner").trim(), | ||
| 63 | + proMap.get("tokens").trim(), | ||
| 64 | + Integer.parseInt(proMap.get("num_threads").trim()), | ||
| 65 | + false); | ||
| 66 | + FeatureConfig featConfig = | ||
| 67 | + new FeatureConfig(sampleRate, Integer.parseInt(proMap.get("feature_dim").trim())); | ||
| 68 | + OnlineRecognizerConfig rcgCfg = | ||
| 69 | + new OnlineRecognizerConfig( | ||
| 70 | + featConfig, | ||
| 71 | + modelCfg, | ||
| 72 | + endCfg, | ||
| 73 | + Boolean.parseBoolean(proMap.get("enable_endpoint_detection").trim()), | ||
| 74 | + proMap.get("decoding_method").trim(), | ||
| 75 | + Integer.parseInt(proMap.get("max_active_paths").trim())); | ||
| 76 | + // create a new Recognizer, first parameter kept for android asset_manager ANDROID_API__ >= 9 | ||
| 77 | + this.ptr = createOnlineRecognizer(new Object(), rcgCfg); | ||
| 78 | + | ||
| 79 | + } catch (Exception e) { | ||
| 80 | + System.err.println(e); | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + // use for android asset_manager ANDROID_API__ >= 9 | ||
| 85 | + public OnlineRecognizer(Object assetManager, String modelCfgPath) { | ||
| 86 | + Map<String, String> proMap = this.readProperties(modelCfgPath); | ||
| 87 | + try { | ||
| 88 | + int sampleRate = Integer.parseInt(proMap.get("sample_rate").trim()); | ||
| 89 | + this.sampleRate = sampleRate; | ||
| 90 | + EndpointRule rule1 = | ||
| 91 | + new EndpointRule( | ||
| 92 | + false, Float.parseFloat(proMap.get("rule1_min_trailing_silence").trim()), 0.0F); | ||
| 93 | + EndpointRule rule2 = | ||
| 94 | + new EndpointRule( | ||
| 95 | + true, Float.parseFloat(proMap.get("rule2_min_trailing_silence").trim()), 0.0F); | ||
| 96 | + EndpointRule rule3 = | ||
| 97 | + new EndpointRule( | ||
| 98 | + false, 0.0F, Float.parseFloat(proMap.get("rule3_min_utterance_length").trim())); | ||
| 99 | + EndpointConfig endCfg = new EndpointConfig(rule1, rule2, rule3); | ||
| 100 | + OnlineTransducerModelConfig modelCfg = | ||
| 101 | + new OnlineTransducerModelConfig( | ||
| 102 | + proMap.get("encoder").trim(), | ||
| 103 | + proMap.get("decoder").trim(), | ||
| 104 | + proMap.get("joiner").trim(), | ||
| 105 | + proMap.get("tokens").trim(), | ||
| 106 | + Integer.parseInt(proMap.get("num_threads").trim()), | ||
| 107 | + false); | ||
| 108 | + FeatureConfig featConfig = | ||
| 109 | + new FeatureConfig(sampleRate, Integer.parseInt(proMap.get("feature_dim").trim())); | ||
| 110 | + OnlineRecognizerConfig rcgCfg = | ||
| 111 | + new OnlineRecognizerConfig( | ||
| 112 | + featConfig, | ||
| 113 | + modelCfg, | ||
| 114 | + endCfg, | ||
| 115 | + Boolean.parseBoolean(proMap.get("enable_endpoint_detection").trim()), | ||
| 116 | + proMap.get("decoding_method").trim(), | ||
| 117 | + Integer.parseInt(proMap.get("max_active_paths").trim())); | ||
| 118 | + // create a new Recognizer, first parameter kept for android asset_manager ANDROID_API__ >= 9 | ||
| 119 | + this.ptr = createOnlineRecognizer(assetManager, rcgCfg); | ||
| 120 | + | ||
| 121 | + } catch (Exception e) { | ||
| 122 | + System.err.println(e); | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + // set onlineRecognizer by parameter | ||
| 127 | + public OnlineRecognizer( | ||
| 128 | + String tokens, | ||
| 129 | + String encoder, | ||
| 130 | + String decoder, | ||
| 131 | + String joiner, | ||
| 132 | + int numThreads, | ||
| 133 | + int sampleRate, | ||
| 134 | + int featureDim, | ||
| 135 | + boolean enableEndpointDetection, | ||
| 136 | + float rule1MinTrailingSilence, | ||
| 137 | + float rule2MinTrailingSilence, | ||
| 138 | + float rule3MinUtteranceLength, | ||
| 139 | + String decodingMethod, | ||
| 140 | + int maxActivePaths) { | ||
| 141 | + this.sampleRate = sampleRate; | ||
| 142 | + EndpointRule rule1 = new EndpointRule(false, rule1MinTrailingSilence, 0.0F); | ||
| 143 | + EndpointRule rule2 = new EndpointRule(true, rule2MinTrailingSilence, 0.0F); | ||
| 144 | + EndpointRule rule3 = new EndpointRule(false, 0.0F, rule3MinUtteranceLength); | ||
| 145 | + EndpointConfig endCfg = new EndpointConfig(rule1, rule2, rule3); | ||
| 146 | + OnlineTransducerModelConfig modelCfg = | ||
| 147 | + new OnlineTransducerModelConfig(encoder, decoder, joiner, tokens, numThreads, false); | ||
| 148 | + FeatureConfig featConfig = new FeatureConfig(sampleRate, featureDim); | ||
| 149 | + OnlineRecognizerConfig rcgCfg = | ||
| 150 | + new OnlineRecognizerConfig( | ||
| 151 | + featConfig, | ||
| 152 | + modelCfg, | ||
| 153 | + endCfg, | ||
| 154 | + enableEndpointDetection, | ||
| 155 | + decodingMethod, | ||
| 156 | + maxActivePaths); | ||
| 157 | + // create a new Recognizer, first parameter kept for android asset_manager ANDROID_API__ >= 9 | ||
| 158 | + this.ptr = createOnlineRecognizer(new Object(), rcgCfg); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + private Map<String, String> readProperties(String modelCfgPath) { | ||
| 162 | + // read and parse config file | ||
| 163 | + Properties props = new Properties(); | ||
| 164 | + Map<String, String> proMap = new HashMap<>(); | ||
| 165 | + try { | ||
| 166 | + File file = new File(modelCfgPath); | ||
| 167 | + if (!file.exists()) { | ||
| 168 | + System.out.println("model cfg file not exists!"); | ||
| 169 | + System.exit(0); | ||
| 170 | + } | ||
| 171 | + InputStream in = new BufferedInputStream(new FileInputStream(modelCfgPath)); | ||
| 172 | + props.load(in); | ||
| 173 | + Enumeration en = props.propertyNames(); | ||
| 174 | + while (en.hasMoreElements()) { | ||
| 175 | + String key = (String) en.nextElement(); | ||
| 176 | + String Property = props.getProperty(key); | ||
| 177 | + proMap.put(key, Property); | ||
| 178 | + // System.out.println(key+"="+Property); | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + } catch (Exception e) { | ||
| 182 | + e.printStackTrace(); | ||
| 183 | + } | ||
| 184 | + return proMap; | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + public void decodeStream(OnlineStream s) throws Exception { | ||
| 188 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 189 | + long streamPtr = s.getPtr(); | ||
| 190 | + if (streamPtr == 0) throw new Exception("null exception for stream ptr"); | ||
| 191 | + // when feeded samples to engine, call DecodeStream to let it process | ||
| 192 | + decodeStream(this.ptr, streamPtr); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + public void decodeStreams(OnlineStream[] ssOjb) throws Exception { | ||
| 196 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 197 | + // decode for multiple streams | ||
| 198 | + long[] ss = new long[ssOjb.length]; | ||
| 199 | + for (int i = 0; i < ssOjb.length; i++) { | ||
| 200 | + ss[i] = ssOjb[i].getPtr(); | ||
| 201 | + if (ss[i] == 0) throw new Exception("null exception for stream ptr"); | ||
| 202 | + } | ||
| 203 | + decodeStreams(this.ptr, ss); | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + public boolean isReady(OnlineStream s) throws Exception { | ||
| 207 | + // whether the engine is ready for decode | ||
| 208 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 209 | + long streamPtr = s.getPtr(); | ||
| 210 | + if (streamPtr == 0) throw new Exception("null exception for stream ptr"); | ||
| 211 | + return isReady(this.ptr, streamPtr); | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + public String getResult(OnlineStream s) throws Exception { | ||
| 215 | + // get text from the engine | ||
| 216 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 217 | + long streamPtr = s.getPtr(); | ||
| 218 | + if (streamPtr == 0) throw new Exception("null exception for stream ptr"); | ||
| 219 | + return getResult(this.ptr, streamPtr); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + public boolean isEndpoint(OnlineStream s) throws Exception { | ||
| 223 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 224 | + long streamPtr = s.getPtr(); | ||
| 225 | + if (streamPtr == 0) throw new Exception("null exception for stream ptr"); | ||
| 226 | + return isEndpoint(this.ptr, streamPtr); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + public void reSet(OnlineStream s) throws Exception { | ||
| 230 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 231 | + long streamPtr = s.getPtr(); | ||
| 232 | + if (streamPtr == 0) throw new Exception("null exception for stream ptr"); | ||
| 233 | + reSet(this.ptr, streamPtr); | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + public OnlineStream createStream() throws Exception { | ||
| 237 | + // create one stream for data to feed in | ||
| 238 | + if (this.ptr == 0) throw new Exception("null exception for recognizer ptr"); | ||
| 239 | + long streamPtr = createStream(this.ptr); | ||
| 240 | + OnlineStream stream = new OnlineStream(streamPtr, this.sampleRate); | ||
| 241 | + return stream; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + public float[] readWavFile(String fileName) { | ||
| 245 | + // read data from the filename | ||
| 246 | + Object[] wavdata = readWave(fileName); | ||
| 247 | + Object data = wavdata[0]; // data[0] is float data, data[1] sample rate | ||
| 248 | + | ||
| 249 | + float[] floatData = (float[]) data; | ||
| 250 | + | ||
| 251 | + return floatData; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + // load the libsherpa-onnx-jni.so lib | ||
| 255 | + public static void loadSoLib(String soPath) { | ||
| 256 | + // load libsherpa-onnx-jni.so lib from the path | ||
| 257 | + | ||
| 258 | + System.out.println("so lib path=" + soPath + "\n"); | ||
| 259 | + System.load(soPath.trim()); | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + public static void setSoPath(String soPath) { | ||
| 263 | + OnlineRecognizer.loadSoLib(soPath); | ||
| 264 | + OnlineStream.loadSoLib(soPath); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + protected void finalize() throws Throwable { | ||
| 268 | + release(); | ||
| 269 | + } | ||
| 270 | + | ||
| 271 | + // recognizer release, you'd better call it manually if not use anymore | ||
| 272 | + public void release() { | ||
| 273 | + if (this.ptr == 0) return; | ||
| 274 | + deleteOnlineRecognizer(this.ptr); | ||
| 275 | + this.ptr = 0; | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + // stream release, you'd better call it manually if not use anymore | ||
| 279 | + public void releaseStream(OnlineStream s) { | ||
| 280 | + s.release(); | ||
| 281 | + } | ||
| 282 | + // JNI interface libsherpa-onnx-jni.so | ||
| 283 | + | ||
| 284 | + private native Object[] readWave(String fileName); | ||
| 285 | + | ||
| 286 | + private native String getResult(long ptr, long streamPtr); | ||
| 287 | + | ||
| 288 | + private native void decodeStream(long ptr, long streamPtr); | ||
| 289 | + | ||
| 290 | + private native void decodeStreams(long ptr, long[] ssPtr); | ||
| 291 | + | ||
| 292 | + private native boolean isReady(long ptr, long streamPtr); | ||
| 293 | + | ||
| 294 | + // first parameter keep for android asset_manager ANDROID_API__ >= 9 | ||
| 295 | + private native long createOnlineRecognizer(Object asset, OnlineRecognizerConfig config); | ||
| 296 | + | ||
| 297 | + private native long createStream(long ptr); | ||
| 298 | + | ||
| 299 | + private native void deleteOnlineRecognizer(long ptr); | ||
| 300 | + | ||
| 301 | + private native boolean isEndpoint(long ptr, long streamPtr); | ||
| 302 | + | ||
| 303 | + private native void reSet(long ptr, long streamPtr); | ||
| 304 | +} |
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +package com.k2fsa.sherpa.onnx; | ||
| 6 | + | ||
| 7 | +public class OnlineRecognizerConfig { | ||
| 8 | + private final FeatureConfig featConfig; | ||
| 9 | + private final OnlineTransducerModelConfig modelConfig; | ||
| 10 | + private final EndpointConfig endpointConfig; | ||
| 11 | + private final boolean enableEndpoint; | ||
| 12 | + private final String decodingMethod; | ||
| 13 | + private final int maxActivePaths; | ||
| 14 | + | ||
| 15 | + public OnlineRecognizerConfig( | ||
| 16 | + FeatureConfig featConfig, | ||
| 17 | + OnlineTransducerModelConfig modelConfig, | ||
| 18 | + EndpointConfig endpointConfig, | ||
| 19 | + boolean enableEndpoint, | ||
| 20 | + String decodingMethod, | ||
| 21 | + int maxActivePaths) { | ||
| 22 | + this.featConfig = featConfig; | ||
| 23 | + this.modelConfig = modelConfig; | ||
| 24 | + this.endpointConfig = endpointConfig; | ||
| 25 | + this.enableEndpoint = enableEndpoint; | ||
| 26 | + this.decodingMethod = decodingMethod; | ||
| 27 | + this.maxActivePaths = maxActivePaths; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public FeatureConfig getFeatConfig() { | ||
| 31 | + return featConfig; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + public OnlineTransducerModelConfig getModelConfig() { | ||
| 35 | + return modelConfig; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public EndpointConfig getEndpointConfig() { | ||
| 39 | + return endpointConfig; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + public boolean isEnableEndpoint() { | ||
| 43 | + return enableEndpoint; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public String getDecodingMethod() { | ||
| 47 | + return decodingMethod; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public int getMaxActivePaths() { | ||
| 51 | + return maxActivePaths; | ||
| 52 | + } | ||
| 53 | +} |
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | +// Stream is used for feeding data to the asr engine | ||
| 5 | +package com.k2fsa.sherpa.onnx; | ||
| 6 | + | ||
| 7 | +import java.io.*; | ||
| 8 | +import java.util.*; | ||
| 9 | + | ||
| 10 | +public class OnlineStream { | ||
| 11 | + private long ptr = 0; // this is the stream ptr | ||
| 12 | + | ||
| 13 | + private int sampleRate = 16000; | ||
| 14 | + // assign ptr to this stream in construction | ||
| 15 | + public OnlineStream(long ptr, int sampleRate) { | ||
| 16 | + this.ptr = ptr; | ||
| 17 | + this.sampleRate = sampleRate; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public long getPtr() { | ||
| 21 | + return ptr; | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public void acceptWaveform(float[] samples) throws Exception { | ||
| 25 | + if (this.ptr == 0) throw new Exception("null exception for stream ptr"); | ||
| 26 | + | ||
| 27 | + // feed wave data to asr engine | ||
| 28 | + acceptWaveform(this.ptr, this.sampleRate, samples); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + public void inputFinished() { | ||
| 32 | + // add some tail padding | ||
| 33 | + int padLen = (int) (this.sampleRate * 0.3); // 0.3 seconds at 16 kHz sample rate | ||
| 34 | + float tailPaddings[] = new float[padLen]; // default value is 0 | ||
| 35 | + acceptWaveform(this.ptr, this.sampleRate, tailPaddings); | ||
| 36 | + | ||
| 37 | + // tell the engine all data are feeded | ||
| 38 | + inputFinished(this.ptr); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public static void loadSoLib(String soPath) { | ||
| 42 | + // load .so lib from the path | ||
| 43 | + System.load(soPath.trim()); // ("sherpa-onnx-jni-java"); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public void release() { | ||
| 47 | + // stream object must be release after used | ||
| 48 | + if (this.ptr == 0) return; | ||
| 49 | + deleteStream(this.ptr); | ||
| 50 | + this.ptr = 0; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + protected void finalize() throws Throwable { | ||
| 54 | + release(); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + public boolean isLastFrame() throws Exception { | ||
| 58 | + if (this.ptr == 0) throw new Exception("null exception for stream ptr"); | ||
| 59 | + return isLastFrame(this.ptr); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + public void reSet() throws Exception { | ||
| 63 | + if (this.ptr == 0) throw new Exception("null exception for stream ptr"); | ||
| 64 | + reSet(this.ptr); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + public int featureDim() throws Exception { | ||
| 68 | + if (this.ptr == 0) throw new Exception("null exception for stream ptr"); | ||
| 69 | + return featureDim(this.ptr); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + // JNI interface libsherpa-onnx-jni.so | ||
| 73 | + private native void acceptWaveform(long ptr, int sampleRate, float[] samples); | ||
| 74 | + | ||
| 75 | + private native void inputFinished(long ptr); | ||
| 76 | + | ||
| 77 | + private native void deleteStream(long ptr); | ||
| 78 | + | ||
| 79 | + private native int numFramesReady(long ptr); | ||
| 80 | + | ||
| 81 | + private native boolean isLastFrame(long ptr); | ||
| 82 | + | ||
| 83 | + private native void reSet(long ptr); | ||
| 84 | + | ||
| 85 | + private native int featureDim(long ptr); | ||
| 86 | +} |
| 1 | +/* | ||
| 2 | + * // Copyright 2022-2023 by zhaoming | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +package com.k2fsa.sherpa.onnx; | ||
| 6 | + | ||
| 7 | +public class OnlineTransducerModelConfig { | ||
| 8 | + private final String encoder; | ||
| 9 | + private final String decoder; | ||
| 10 | + private final String joiner; | ||
| 11 | + private final String tokens; | ||
| 12 | + private final int numThreads; | ||
| 13 | + private final boolean debug; | ||
| 14 | + | ||
| 15 | + public OnlineTransducerModelConfig( | ||
| 16 | + String encoder, String decoder, String joiner, String tokens, int numThreads, boolean debug) { | ||
| 17 | + this.encoder = encoder; | ||
| 18 | + this.decoder = decoder; | ||
| 19 | + this.joiner = joiner; | ||
| 20 | + this.tokens = tokens; | ||
| 21 | + this.numThreads = numThreads; | ||
| 22 | + this.debug = debug; | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public String getEncoder() { | ||
| 26 | + return encoder; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + public String getDecoder() { | ||
| 30 | + return decoder; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + public String getJoiner() { | ||
| 34 | + return joiner; | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | + public String getTokens() { | ||
| 38 | + return tokens; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public int getNumThreads() { | ||
| 42 | + return numThreads; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public boolean getDebug() { | ||
| 46 | + return debug; | ||
| 47 | + } | ||
| 48 | +} |
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | // | 2 | // |
| 3 | // Copyright (c) 2022-2023 Xiaomi Corporation | 3 | // Copyright (c) 2022-2023 Xiaomi Corporation |
| 4 | // 2022 Pingfeng Luo | 4 | // 2022 Pingfeng Luo |
| 5 | +// 2023 Zhaoming | ||
| 5 | 6 | ||
| 6 | // TODO(fangjun): Add documentation to functions/methods in this file | 7 | // TODO(fangjun): Add documentation to functions/methods in this file |
| 7 | // and also show how to use them with kotlin, possibly with java. | 8 | // and also show how to use them with kotlin, possibly with java. |
| @@ -12,7 +13,6 @@ | @@ -12,7 +13,6 @@ | ||
| 12 | 13 | ||
| 13 | #include <strstream> | 14 | #include <strstream> |
| 14 | #include <utility> | 15 | #include <utility> |
| 15 | - | ||
| 16 | #if __ANDROID_API__ >= 9 | 16 | #if __ANDROID_API__ >= 9 |
| 17 | #include "android/asset_manager.h" | 17 | #include "android/asset_manager.h" |
| 18 | #include "android/asset_manager_jni.h" | 18 | #include "android/asset_manager_jni.h" |
| @@ -207,7 +207,6 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_SherpaOnnx_new( | @@ -207,7 +207,6 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_SherpaOnnx_new( | ||
| 207 | SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr); | 207 | SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr); |
| 208 | } | 208 | } |
| 209 | #endif | 209 | #endif |
| 210 | - | ||
| 211 | auto config = sherpa_onnx::GetConfig(env, _config); | 210 | auto config = sherpa_onnx::GetConfig(env, _config); |
| 212 | SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str()); | 211 | SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str()); |
| 213 | auto model = new sherpa_onnx::SherpaOnnx( | 212 | auto model = new sherpa_onnx::SherpaOnnx( |
| @@ -301,7 +300,7 @@ Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave( | @@ -301,7 +300,7 @@ Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave( | ||
| 301 | SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr); | 300 | SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr); |
| 302 | exit(-1); | 301 | exit(-1); |
| 303 | } | 302 | } |
| 304 | - | 303 | + SHERPA_ONNX_LOGE("Failed to read %s", p_filename); |
| 305 | std::vector<char> buffer = sherpa_onnx::ReadFile(mgr, p_filename); | 304 | std::vector<char> buffer = sherpa_onnx::ReadFile(mgr, p_filename); |
| 306 | 305 | ||
| 307 | std::istrstream is(buffer.data(), buffer.size()); | 306 | std::istrstream is(buffer.data(), buffer.size()); |
| @@ -332,3 +331,186 @@ Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave( | @@ -332,3 +331,186 @@ Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave( | ||
| 332 | 331 | ||
| 333 | return obj_arr; | 332 | return obj_arr; |
| 334 | } | 333 | } |
| 334 | + | ||
| 335 | +// ******warpper for OnlineRecognizer******* | ||
| 336 | + | ||
| 337 | +// wav reader for java interface | ||
| 338 | +SHERPA_ONNX_EXTERN_C | ||
| 339 | +JNIEXPORT jobjectArray JNICALL | ||
| 340 | +Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_readWave(JNIEnv *env, | ||
| 341 | + jclass /*cls*/, | ||
| 342 | + jstring filename) { | ||
| 343 | + auto data = Java_com_k2fsa_sherpa_onnx_WaveReader_00024Companion_readWave( | ||
| 344 | + env, nullptr, nullptr, filename); | ||
| 345 | + return data; | ||
| 346 | +} | ||
| 347 | + | ||
| 348 | +SHERPA_ONNX_EXTERN_C | ||
| 349 | +JNIEXPORT jlong JNICALL | ||
| 350 | + | ||
| 351 | +Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_createOnlineRecognizer( | ||
| 352 | + | ||
| 353 | + JNIEnv *env, jobject /*obj*/, jobject asset_manager, jobject _config) { | ||
| 354 | +#if __ANDROID_API__ >= 9 | ||
| 355 | + AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager); | ||
| 356 | + if (!mgr) { | ||
| 357 | + SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr); | ||
| 358 | + } | ||
| 359 | +#endif | ||
| 360 | + sherpa_onnx::OnlineRecognizerConfig config = | ||
| 361 | + sherpa_onnx::GetConfig(env, _config); | ||
| 362 | + SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str()); | ||
| 363 | + auto p_recognizer = new sherpa_onnx::OnlineRecognizer( | ||
| 364 | +#if __ANDROID_API__ >= 9 | ||
| 365 | + mgr, | ||
| 366 | +#endif | ||
| 367 | + config); | ||
| 368 | + return (jlong)p_recognizer; | ||
| 369 | +} | ||
| 370 | + | ||
| 371 | +SHERPA_ONNX_EXTERN_C | ||
| 372 | +JNIEXPORT void JNICALL | ||
| 373 | +Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_deleteOnlineRecognizer( | ||
| 374 | + JNIEnv *env, jobject /*obj*/, jlong ptr) { | ||
| 375 | + delete reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 376 | +} | ||
| 377 | + | ||
| 378 | +SHERPA_ONNX_EXTERN_C | ||
| 379 | +JNIEXPORT jlong JNICALL | ||
| 380 | +Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_createStream(JNIEnv *env, | ||
| 381 | + jobject /*obj*/, | ||
| 382 | + jlong ptr) { | ||
| 383 | + std::unique_ptr<sherpa_onnx::OnlineStream> s = | ||
| 384 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr)->CreateStream(); | ||
| 385 | + sherpa_onnx::OnlineStream *p_stream = s.release(); | ||
| 386 | + return reinterpret_cast<jlong>(p_stream); | ||
| 387 | +} | ||
| 388 | + | ||
| 389 | +SHERPA_ONNX_EXTERN_C | ||
| 390 | +JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_isReady( | ||
| 391 | + JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) { | ||
| 392 | + sherpa_onnx::OnlineRecognizer *model = | ||
| 393 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 394 | + sherpa_onnx::OnlineStream *s = | ||
| 395 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 396 | + return model->IsReady(s); | ||
| 397 | +} | ||
| 398 | + | ||
| 399 | +SHERPA_ONNX_EXTERN_C | ||
| 400 | +JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_decodeStream( | ||
| 401 | + JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) { | ||
| 402 | + sherpa_onnx::OnlineRecognizer *model = | ||
| 403 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 404 | + sherpa_onnx::OnlineStream *s = | ||
| 405 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 406 | + model->DecodeStream(s); | ||
| 407 | +} | ||
| 408 | + | ||
| 409 | +SHERPA_ONNX_EXTERN_C | ||
| 410 | +JNIEXPORT void JNICALL | ||
| 411 | +Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_decodeStreams(JNIEnv *env, | ||
| 412 | + jobject /*obj*/, | ||
| 413 | + jlong ptr, | ||
| 414 | + jlongArray ss_ptr, | ||
| 415 | + jint stream_size) { | ||
| 416 | + sherpa_onnx::OnlineRecognizer *model = | ||
| 417 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 418 | + jlong *p = env->GetLongArrayElements(ss_ptr, nullptr); | ||
| 419 | + jsize n = env->GetArrayLength(ss_ptr); | ||
| 420 | + std::vector<sherpa_onnx::OnlineStream *> p_ss(n); | ||
| 421 | + for (int32_t i = 0; i != n; ++i) { | ||
| 422 | + p_ss[i] = reinterpret_cast<sherpa_onnx::OnlineStream *>(p[i]); | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + model->DecodeStreams(p_ss.data(), n); | ||
| 426 | + env->ReleaseLongArrayElements(ss_ptr, p, JNI_ABORT); | ||
| 427 | +} | ||
| 428 | + | ||
| 429 | +SHERPA_ONNX_EXTERN_C | ||
| 430 | +JNIEXPORT jstring JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_getResult( | ||
| 431 | + JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) { | ||
| 432 | + sherpa_onnx::OnlineRecognizer *model = | ||
| 433 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 434 | + sherpa_onnx::OnlineStream *s = | ||
| 435 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 436 | + sherpa_onnx::OnlineRecognizerResult result = model->GetResult(s); | ||
| 437 | + return env->NewStringUTF(result.ToString().c_str()); | ||
| 438 | +} | ||
| 439 | + | ||
| 440 | +SHERPA_ONNX_EXTERN_C | ||
| 441 | +JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_isEndpoint( | ||
| 442 | + JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) { | ||
| 443 | + sherpa_onnx::OnlineRecognizer *model = | ||
| 444 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 445 | + sherpa_onnx::OnlineStream *s = | ||
| 446 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 447 | + return model->IsEndpoint(s); | ||
| 448 | +} | ||
| 449 | + | ||
| 450 | +SHERPA_ONNX_EXTERN_C | ||
| 451 | +JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineRecognizer_reSet( | ||
| 452 | + JNIEnv *env, jobject /*obj*/, jlong ptr, jlong s_ptr) { | ||
| 453 | + sherpa_onnx::OnlineRecognizer *model = | ||
| 454 | + reinterpret_cast<sherpa_onnx::OnlineRecognizer *>(ptr); | ||
| 455 | + sherpa_onnx::OnlineStream *s = | ||
| 456 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 457 | + model->Reset(s); | ||
| 458 | +} | ||
| 459 | + | ||
| 460 | +// *********for OnlineStream ********* | ||
| 461 | +SHERPA_ONNX_EXTERN_C | ||
| 462 | +JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_acceptWaveform( | ||
| 463 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr, jint sample_rate, | ||
| 464 | + jfloatArray waveform) { | ||
| 465 | + sherpa_onnx::OnlineStream *s = | ||
| 466 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 467 | + jfloat *p = env->GetFloatArrayElements(waveform, nullptr); | ||
| 468 | + jsize n = env->GetArrayLength(waveform); | ||
| 469 | + s->AcceptWaveform(sample_rate, p, n); | ||
| 470 | + env->ReleaseFloatArrayElements(waveform, p, JNI_ABORT); | ||
| 471 | +} | ||
| 472 | + | ||
| 473 | +SHERPA_ONNX_EXTERN_C | ||
| 474 | +JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_inputFinished( | ||
| 475 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr) { | ||
| 476 | + sherpa_onnx::OnlineStream *s = | ||
| 477 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 478 | + s->InputFinished(); | ||
| 479 | +} | ||
| 480 | + | ||
| 481 | +SHERPA_ONNX_EXTERN_C | ||
| 482 | +JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_deleteStream( | ||
| 483 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr) { | ||
| 484 | + delete reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 485 | +} | ||
| 486 | + | ||
| 487 | +SHERPA_ONNX_EXTERN_C | ||
| 488 | +JNIEXPORT jint JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_numFramesReady( | ||
| 489 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr) { | ||
| 490 | + sherpa_onnx::OnlineStream *s = | ||
| 491 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 492 | + return s->NumFramesReady(); | ||
| 493 | +} | ||
| 494 | + | ||
| 495 | +SHERPA_ONNX_EXTERN_C | ||
| 496 | +JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_isLastFrame( | ||
| 497 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr, jint frame) { | ||
| 498 | + sherpa_onnx::OnlineStream *s = | ||
| 499 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 500 | + return s->IsLastFrame(frame); | ||
| 501 | +} | ||
| 502 | +SHERPA_ONNX_EXTERN_C | ||
| 503 | +JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_reSet( | ||
| 504 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr) { | ||
| 505 | + sherpa_onnx::OnlineStream *s = | ||
| 506 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 507 | + s->Reset(); | ||
| 508 | +} | ||
| 509 | + | ||
| 510 | +SHERPA_ONNX_EXTERN_C | ||
| 511 | +JNIEXPORT jint JNICALL Java_com_k2fsa_sherpa_onnx_OnlineStream_featureDim( | ||
| 512 | + JNIEnv *env, jobject /*obj*/, jlong s_ptr) { | ||
| 513 | + sherpa_onnx::OnlineStream *s = | ||
| 514 | + reinterpret_cast<sherpa_onnx::OnlineStream *>(s_ptr); | ||
| 515 | + return s->FeatureDim(); | ||
| 516 | +} |
-
请 注册 或 登录 后发表评论