├── .circleci └── config.yml ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── .yarnrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── android ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ ├── cpp │ ├── CMakeLists.txt │ ├── bin │ │ ├── CMakeLists.txt │ │ ├── api_main.cc │ │ ├── decoder_main.cc │ │ ├── grpc_client_main.cc │ │ ├── grpc_server_main.cc │ │ ├── label_checker_main.cc │ │ ├── websocket_client_main.cc │ │ └── websocket_server_main.cc │ ├── cmake │ │ ├── boost.cmake │ │ ├── gflags.cmake │ │ ├── glog.cmake │ │ ├── grpc.cmake │ │ ├── gtest.cmake │ │ ├── libtorch.cmake │ │ ├── onnx.cmake │ │ ├── openfst.cmake │ │ └── pybind11.cmake │ ├── decoder │ │ ├── CMakeLists.txt │ │ ├── asr_decoder.cc │ │ ├── asr_decoder.h │ │ ├── asr_model.cc │ │ ├── asr_model.h │ │ ├── context_graph.cc │ │ ├── context_graph.h │ │ ├── ctc_endpoint.cc │ │ ├── ctc_endpoint.h │ │ ├── ctc_prefix_beam_search.cc │ │ ├── ctc_prefix_beam_search.h │ │ ├── ctc_wfst_beam_search.cc │ │ ├── ctc_wfst_beam_search.h │ │ ├── onnx_asr_model.cc │ │ ├── onnx_asr_model.h │ │ ├── params.h │ │ ├── search_interface.h │ │ ├── torch_asr_model.cc │ │ └── torch_asr_model.h │ ├── frontend │ │ ├── CMakeLists.txt │ │ ├── fbank.h │ │ ├── feature_pipeline.cc │ │ ├── feature_pipeline.h │ │ ├── fft.cc │ │ ├── fft.h │ │ └── wav.h │ ├── kaldi │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── base │ │ │ ├── io-funcs-inl.h │ │ │ ├── io-funcs.cc │ │ │ ├── io-funcs.h │ │ │ ├── kaldi-common.h │ │ │ ├── kaldi-error.cc │ │ │ ├── kaldi-error.h │ │ │ ├── kaldi-math.cc │ │ │ ├── kaldi-math.h │ │ │ ├── kaldi-types.h │ │ │ └── kaldi-utils.h │ │ ├── decoder │ │ │ ├── lattice-faster-decoder.cc │ │ │ ├── lattice-faster-decoder.h │ │ │ ├── lattice-faster-online-decoder.cc │ │ │ └── lattice-faster-online-decoder.h │ │ ├── fstbin │ │ │ ├── fstaddselfloops.cc │ │ │ ├── fstdeterminizestar.cc │ │ │ ├── fstisstochastic.cc │ │ │ ├── fstminimizeencoded.cc │ │ │ └── fsttablecompose.cc │ │ ├── fstext │ │ │ ├── determinize-lattice-inl.h │ │ │ ├── determinize-lattice.h │ │ │ ├── determinize-star-inl.h │ │ │ ├── determinize-star.h │ │ │ ├── fstext-lib.h │ │ │ ├── fstext-utils-inl.h │ │ │ ├── fstext-utils.h │ │ │ ├── kaldi-fst-io-inl.h │ │ │ ├── kaldi-fst-io.cc │ │ │ ├── kaldi-fst-io.h │ │ │ ├── lattice-utils-inl.h │ │ │ ├── lattice-utils.h │ │ │ ├── lattice-weight.h │ │ │ ├── pre-determinize-inl.h │ │ │ ├── pre-determinize.h │ │ │ ├── remove-eps-local-inl.h │ │ │ ├── remove-eps-local.h │ │ │ └── table-matcher.h │ │ ├── itf │ │ │ ├── decodable-itf.h │ │ │ └── options-itf.h │ │ ├── lat │ │ │ ├── CPPLINT.cfg │ │ │ ├── determinize-lattice-pruned.cc │ │ │ ├── determinize-lattice-pruned.h │ │ │ ├── kaldi-lattice.cc │ │ │ ├── kaldi-lattice.h │ │ │ ├── lattice-functions.cc │ │ │ └── lattice-functions.h │ │ ├── lm │ │ │ ├── arpa-file-parser.cc │ │ │ ├── arpa-file-parser.h │ │ │ ├── arpa-lm-compiler.cc │ │ │ └── arpa-lm-compiler.h │ │ ├── lmbin │ │ │ └── arpa2fst.cc │ │ └── util │ │ │ ├── basic-filebuf.h │ │ │ ├── const-integer-set-inl.h │ │ │ ├── const-integer-set.h │ │ │ ├── hash-list-inl.h │ │ │ ├── hash-list.h │ │ │ ├── kaldi-io-inl.h │ │ │ ├── kaldi-io.cc │ │ │ ├── kaldi-io.h │ │ │ ├── kaldi-pipebuf.h │ │ │ ├── parse-options.cc │ │ │ ├── parse-options.h │ │ │ ├── simple-io-funcs.cc │ │ │ ├── simple-io-funcs.h │ │ │ ├── stl-utils.h │ │ │ ├── text-utils.cc │ │ │ └── text-utils.h │ ├── patch │ │ ├── CPPLINT.cfg │ │ └── openfst │ │ │ └── src │ │ │ ├── CMakeLists.txt │ │ │ ├── extensions │ │ │ └── special │ │ │ │ └── CMakeLists.txt │ │ │ └── include │ │ │ └── fst │ │ │ ├── flags.h │ │ │ └── log.h │ ├── post_processor │ │ ├── CMakeLists.txt │ │ ├── post_processor.cc │ │ └── post_processor.h │ ├── utils │ │ ├── CMakeLists.txt │ │ ├── blocking_queue.h │ │ ├── file.h │ │ ├── flags.h │ │ ├── json.h │ │ ├── log.h │ │ ├── string.cc │ │ ├── string.h │ │ ├── thread_pool.h │ │ ├── timer.h │ │ ├── utils.cc │ │ └── utils.h │ └── wenet.cc │ └── java │ └── com │ └── reactnativewenet │ ├── WenetModule.java │ ├── WenetPackage.java │ └── wenet │ ├── AudioEncoderOffline.java │ ├── AudioSoftwarePollerOffline.java │ ├── OfflineRecognition.java │ └── Recognize.java ├── babel.config.js ├── example ├── .bundle │ └── config ├── .ruby-version ├── Gemfile ├── Gemfile.lock ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── reactnativewenet │ │ │ │ └── ReactNativeFlipper.java │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── reactnativewenet │ │ │ │ ├── MainActivity.java │ │ │ │ ├── MainApplication.java │ │ │ │ └── newarchitecture │ │ │ │ ├── MainApplicationReactNativeHost.java │ │ │ │ ├── components │ │ │ │ └── MainComponentsRegistry.java │ │ │ │ └── modules │ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java │ │ │ ├── jni │ │ │ ├── Android.mk │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ ├── MainApplicationModuleProvider.h │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ ├── MainComponentsRegistry.cpp │ │ │ ├── MainComponentsRegistry.h │ │ │ └── OnLoad.cpp │ │ │ └── res │ │ │ ├── drawable │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── babel.config.js ├── index.tsx ├── ios │ ├── File.swift │ ├── Podfile │ ├── WenetExample-Bridging-Header.h │ ├── WenetExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── WenetExample.xcscheme │ ├── WenetExample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── WenetExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m ├── metro.config.js ├── package-lock.json ├── package.json ├── react-native.config.js ├── src │ └── App.tsx └── yarn.lock ├── ios ├── Wenet-Bridging-Header.h ├── Wenet.m ├── Wenet.swift └── Wenet.xcodeproj │ └── project.pbxproj ├── lefthook.yml ├── package.json ├── react-native-wenet.podspec ├── scripts └── bootstrap.js ├── src ├── __tests__ │ └── index.test.tsx ├── index.tsx ├── types.ts └── wenet.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | default: 5 | docker: 6 | - image: circleci/node:16 7 | working_directory: ~/project 8 | 9 | commands: 10 | attach_project: 11 | steps: 12 | - attach_workspace: 13 | at: ~/project 14 | 15 | jobs: 16 | install-dependencies: 17 | executor: default 18 | steps: 19 | - checkout 20 | - attach_project 21 | - restore_cache: 22 | keys: 23 | - dependencies-{{ checksum "package.json" }} 24 | - dependencies- 25 | - restore_cache: 26 | keys: 27 | - dependencies-example-{{ checksum "example/package.json" }} 28 | - dependencies-example- 29 | - run: 30 | name: Install dependencies 31 | command: | 32 | yarn install --cwd example --frozen-lockfile 33 | yarn install --frozen-lockfile 34 | - save_cache: 35 | key: dependencies-{{ checksum "package.json" }} 36 | paths: node_modules 37 | - save_cache: 38 | key: dependencies-example-{{ checksum "example/package.json" }} 39 | paths: example/node_modules 40 | - persist_to_workspace: 41 | root: . 42 | paths: . 43 | 44 | lint: 45 | executor: default 46 | steps: 47 | - attach_project 48 | - run: 49 | name: Lint files 50 | command: | 51 | yarn lint 52 | 53 | typescript: 54 | executor: default 55 | steps: 56 | - attach_project 57 | - run: 58 | name: Typecheck files 59 | command: | 60 | yarn typescript 61 | 62 | unit-tests: 63 | executor: default 64 | steps: 65 | - attach_project 66 | - run: 67 | name: Run unit tests 68 | command: | 69 | yarn test --coverage 70 | - store_artifacts: 71 | path: coverage 72 | destination: coverage 73 | 74 | build-package: 75 | executor: default 76 | steps: 77 | - attach_project 78 | - run: 79 | name: Build package 80 | command: | 81 | yarn prepare 82 | 83 | workflows: 84 | build-and-test: 85 | jobs: 86 | - install-dependencies 87 | - lint: 88 | requires: 89 | - install-dependencies 90 | - typescript: 91 | requires: 92 | - install-dependencies 93 | - unit-tests: 94 | requires: 95 | - install-dependencies 96 | - build-package: 97 | requires: 98 | - install-dependencies 99 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # Ruby 48 | example/vendor/ 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-debug.log 55 | yarn-error.log 56 | 57 | # BUCK 58 | buck-out/ 59 | \.buckd/ 60 | android/app/libs 61 | android/keystores/debug.keystore 62 | 63 | # Expo 64 | .expo/* 65 | 66 | # generated by bob 67 | lib/ 68 | android/src/main/assets/ 69 | example/android/app/src/main/assets/ 70 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | # Override Yarn command so we can automatically setup the repo on running `yarn` 2 | 3 | yarn-path "scripts/bootstrap.js" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Hannes Bezuidenhout 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-wenet 2 | 3 | React Native Speech to Text using wenet 4 | 5 | ## Installation 6 | 7 | ```sh 8 | #Not yet ready 9 | npm install react-native-wenet 10 | ``` 11 | 12 | ### Example App 13 | 14 | To run the example app just fork the repository and run the following. 15 | Need to provide the wenet model in the example app folder inside `android\app\src\main\assets` 16 | 17 | ```sh 18 | yarn 19 | yarn example android 20 | ``` 21 | 22 | ## About 23 | 24 | This is a react native module of the amazing [Wenet](https://github.com/wenet-e2e/wenet) framework. We at [Writtan](https://www.writtan.com) absolutely love the simplicity of wenet and plan on integrating it into our own app. We would appreciate any help with this module please see the todo at the bottom. 25 | 26 | ## Disclaimer 27 | 28 | This is a work in progress and the package might change drastically in the future! 29 | 30 | ## Android 31 | 32 | You are required to provide a wenet model to use this package. In your file tree it should be located in `android\app\src\main\assets`. 33 | 34 | ## IOS 35 | 36 | No support for ios yet :( 37 | 38 | ## Usage 39 | 40 | ```js 41 | import Wenet, { Event } from 'react-native-wenet'; 42 | 43 | React.useEffect(() => { 44 | Wenet.setupSTT(); 45 | //Need to request audio permission here 46 | }, []); 47 | 48 | const handleStart = async () => { 49 | Wenet.startSTT(); //Start the service 50 | Wenet.addEventListener(Event.Result, (data) => { 51 | setResult(data); //Returns the results 52 | }); 53 | }; 54 | 55 | const handleStop = async () => { 56 | Wenet.stopSTT(); 57 | }; 58 | ``` 59 | 60 | ## Todo 61 | 62 | - [ ] Create documentation 63 | - [ ] Convert module to send data with JSI 64 | - [ ] Add timestamps to the final results 65 | - [ ] Separate Final result from partial result (Not just 1 big final) 66 | - [ ] Add ability to download new models inside the app 67 | - [ ] Reduce package size (maybe move to pytorch-android-light, see what c++ can be removed) 68 | - [ ] Create ios version (also not implemented in wenet yet) 69 | 70 | ## Contributing 71 | 72 | See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. 73 | 74 | ## Acknowledge 75 | 76 | 1. Most of the code is written by the good people at [Wenet](https://github.com/wenet-e2e/wenet) 77 | 2. I plan on using a lot of [Playtorch](https://github.com/facebookresearch/playtorch) code for writing jsi (linking c++ and react native) 78 | 79 | ## License 80 | 81 | MIT 82 | 83 | --- 84 | 85 | Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) 86 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | Wenet_kotlinVersion=1.7.0 2 | Wenet_minSdkVersion=21 3 | Wenet_targetSdkVersion=31 4 | Wenet_compileSdkVersion=31 5 | Wenet_ndkversion=21.4.7075529 6 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/src/main/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.4.1) 2 | set(TARGET wenet) 3 | project(${TARGET} CXX) 4 | set(CMAKE_CXX_STANDARD 14) 5 | include(ExternalProject) 6 | 7 | option(TORCH "whether to build with Torch" ON) 8 | option(ONNX "whether to build with ONNX" OFF) 9 | set(CMAKE_VERBOSE_MAKEFILE on) 10 | set(build_DIR ${CMAKE_SOURCE_DIR}/../../../build) 11 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 12 | string(REPLACE "-Wl,--exclude-libs,libgcc_real.a" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") 13 | 14 | include(libtorch) 15 | include(openfst) 16 | 17 | include_directories( 18 | ${CMAKE_SOURCE_DIR} 19 | ${CMAKE_SOURCE_DIR}/kaldi 20 | ) 21 | 22 | add_subdirectory(utils) 23 | add_subdirectory(frontend) 24 | add_subdirectory(post_processor) 25 | add_subdirectory(kaldi) # kaldi: wfst based decoder 26 | add_subdirectory(decoder) 27 | 28 | link_libraries(frontend decoder android) 29 | add_library(${TARGET} SHARED wenet.cc) 30 | 31 | add_executable(decoder_main bin/decoder_main.cc) 32 | target_link_libraries(decoder_main PUBLIC libc++_shared.so) 33 | -------------------------------------------------------------------------------- /android/src/main/cpp/bin/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(decoder_main decoder_main.cc) 2 | target_link_libraries(decoder_main PUBLIC decoder) 3 | 4 | add_executable(label_checker_main label_checker_main.cc) 5 | target_link_libraries(label_checker_main PUBLIC decoder) 6 | 7 | if(TORCH) 8 | add_executable(api_main api_main.cc) 9 | target_link_libraries(api_main PUBLIC wenet_api) 10 | endif() 11 | 12 | if(WEBSOCKET) 13 | add_executable(websocket_client_main websocket_client_main.cc) 14 | target_link_libraries(websocket_client_main PUBLIC websocket) 15 | add_executable(websocket_server_main websocket_server_main.cc) 16 | target_link_libraries(websocket_server_main PUBLIC websocket) 17 | endif() 18 | 19 | if(GRPC) 20 | add_executable(grpc_server_main grpc_server_main.cc) 21 | target_link_libraries(grpc_server_main PUBLIC wenet_grpc) 22 | add_executable(grpc_client_main grpc_client_main.cc) 23 | target_link_libraries(grpc_client_main PUBLIC wenet_grpc) 24 | endif() 25 | -------------------------------------------------------------------------------- /android/src/main/cpp/bin/api_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Binbin Zhang (binbzha@qq.com) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "api/wenet_api.h" 16 | #include "frontend/wav.h" 17 | #include "utils/flags.h" 18 | 19 | DEFINE_string(model_dir, "", "model dir path"); 20 | DEFINE_string(wav_path, "", "single wave path"); 21 | DEFINE_bool(enable_timestamp, false, "enable timestamps"); 22 | 23 | int main(int argc, char* argv[]) { 24 | gflags::ParseCommandLineFlags(&argc, &argv, false); 25 | google::InitGoogleLogging(argv[0]); 26 | 27 | wenet_set_log_level(2); 28 | 29 | void* decoder = wenet_init(FLAGS_model_dir.c_str()); 30 | wenet_set_timestamp(decoder, FLAGS_enable_timestamp == true ? 1 : 0); 31 | wenet::WavReader wav_reader(FLAGS_wav_path); 32 | std::vector data(wav_reader.num_samples()); 33 | for (int i = 0; i < wav_reader.num_samples(); i++) { 34 | data[i] = static_cast(*(wav_reader.data() + i)); 35 | } 36 | 37 | for (int i = 0; i < 10; i++) { 38 | // Return the final result when last is 1 39 | wenet_decode(decoder, reinterpret_cast(data.data()), 40 | data.size() * 2, 1); 41 | const char* result = wenet_get_result(decoder); 42 | LOG(INFO) << i << " " << result; 43 | wenet_reset(decoder); 44 | } 45 | wenet_free(decoder); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /android/src/main/cpp/bin/grpc_client_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Ximalaya Speech Team (Xiang Lyu) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "frontend/wav.h" 16 | #include "grpc/grpc_client.h" 17 | #include "utils/flags.h" 18 | #include "utils/timer.h" 19 | 20 | DEFINE_string(hostname, "127.0.0.1", "hostname of websocket server"); 21 | DEFINE_int32(port, 10086, "port of websocket server"); 22 | DEFINE_int32(nbest, 1, "n-best of decode result"); 23 | DEFINE_string(wav_path, "", "test wav file path"); 24 | DEFINE_bool(continuous_decoding, false, "continuous decoding mode"); 25 | 26 | int main(int argc, char* argv[]) { 27 | gflags::ParseCommandLineFlags(&argc, &argv, false); 28 | google::InitGoogleLogging(argv[0]); 29 | wenet::GrpcClient client(FLAGS_hostname, FLAGS_port, FLAGS_nbest, 30 | FLAGS_continuous_decoding); 31 | 32 | wenet::WavReader wav_reader(FLAGS_wav_path); 33 | const int sample_rate = 16000; 34 | // Only support 16K 35 | CHECK_EQ(wav_reader.sample_rate(), sample_rate); 36 | const int num_samples = wav_reader.num_samples(); 37 | std::vector pcm_data(wav_reader.data(), 38 | wav_reader.data() + num_samples); 39 | // Send data every 0.5 second 40 | const float interval = 0.5; 41 | const int sample_interval = interval * sample_rate; 42 | for (int start = 0; start < num_samples; start += sample_interval) { 43 | if (client.done()) { 44 | break; 45 | } 46 | int end = std::min(start + sample_interval, num_samples); 47 | // Convert to short 48 | std::vector data; 49 | data.reserve(end - start); 50 | for (int j = start; j < end; j++) { 51 | data.push_back(static_cast(pcm_data[j])); 52 | } 53 | // Send PCM data 54 | client.SendBinaryData(data.data(), data.size() * sizeof(int16_t)); 55 | VLOG(2) << "Send " << data.size() << " samples"; 56 | std::this_thread::sleep_for( 57 | std::chrono::milliseconds(static_cast(interval * 1000))); 58 | } 59 | wenet::Timer timer; 60 | 61 | client.Join(); 62 | VLOG(2) << "Total latency: " << timer.Elapsed() << "ms."; 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /android/src/main/cpp/bin/grpc_server_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Ximalaya Speech Team (Xiang Lyu) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "decoder/params.h" 20 | #include "grpc/grpc_server.h" 21 | #include "utils/log.h" 22 | 23 | DEFINE_int32(port, 10086, "grpc listening port"); 24 | DEFINE_int32(workers, 4, "grpc num workers"); 25 | 26 | using grpc::Server; 27 | using grpc::ServerBuilder; 28 | 29 | int main(int argc, char* argv[]) { 30 | gflags::ParseCommandLineFlags(&argc, &argv, false); 31 | google::InitGoogleLogging(argv[0]); 32 | 33 | auto decode_config = wenet::InitDecodeOptionsFromFlags(); 34 | auto feature_config = wenet::InitFeaturePipelineConfigFromFlags(); 35 | auto decode_resource = wenet::InitDecodeResourceFromFlags(); 36 | 37 | wenet::GrpcServer service(feature_config, decode_config, decode_resource); 38 | grpc::EnableDefaultHealthCheckService(true); 39 | grpc::reflection::InitProtoReflectionServerBuilderPlugin(); 40 | ServerBuilder builder; 41 | std::string address("0.0.0.0:" + std::to_string(FLAGS_port)); 42 | builder.AddListeningPort(address, grpc::InsecureServerCredentials()); 43 | builder.RegisterService(&service); 44 | builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 45 | FLAGS_workers); 46 | std::unique_ptr server(builder.BuildAndStart()); 47 | LOG(INFO) << "Listening at port " << FLAGS_port; 48 | server->Wait(); 49 | google::ShutdownGoogleLogging(); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /android/src/main/cpp/bin/websocket_client_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "frontend/wav.h" 16 | #include "utils/flags.h" 17 | #include "utils/timer.h" 18 | #include "websocket/websocket_client.h" 19 | 20 | DEFINE_string(hostname, "127.0.0.1", "hostname of websocket server"); 21 | DEFINE_int32(port, 10086, "port of websocket server"); 22 | DEFINE_int32(nbest, 1, "n-best of decode result"); 23 | DEFINE_string(wav_path, "", "test wav file path"); 24 | DEFINE_bool(continuous_decoding, false, "continuous decoding mode"); 25 | 26 | int main(int argc, char* argv[]) { 27 | gflags::ParseCommandLineFlags(&argc, &argv, false); 28 | google::InitGoogleLogging(argv[0]); 29 | wenet::WebSocketClient client(FLAGS_hostname, FLAGS_port); 30 | client.set_nbest(FLAGS_nbest); 31 | client.set_continuous_decoding(FLAGS_continuous_decoding); 32 | client.SendStartSignal(); 33 | 34 | wenet::WavReader wav_reader(FLAGS_wav_path); 35 | const int sample_rate = 16000; 36 | // Only support 16K 37 | CHECK_EQ(wav_reader.sample_rate(), sample_rate); 38 | const int num_samples = wav_reader.num_samples(); 39 | // Send data every 0.5 second 40 | const float interval = 0.5; 41 | const int sample_interval = interval * sample_rate; 42 | for (int start = 0; start < num_samples; start += sample_interval) { 43 | if (client.done()) { 44 | break; 45 | } 46 | int end = std::min(start + sample_interval, num_samples); 47 | // Convert to short 48 | std::vector data; 49 | data.reserve(end - start); 50 | for (int j = start; j < end; j++) { 51 | data.push_back(static_cast(wav_reader.data()[j])); 52 | } 53 | // TODO(Binbin Zhang): Network order? 54 | // Send PCM data 55 | client.SendBinaryData(data.data(), data.size() * sizeof(int16_t)); 56 | VLOG(2) << "Send " << data.size() << " samples"; 57 | std::this_thread::sleep_for( 58 | std::chrono::milliseconds(static_cast(interval * 1000))); 59 | } 60 | wenet::Timer timer; 61 | client.SendEndSignal(); 62 | client.Join(); 63 | VLOG(2) << "Total latency: " << timer.Elapsed() << "ms."; 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /android/src/main/cpp/bin/websocket_server_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "decoder/params.h" 16 | #include "utils/log.h" 17 | #include "websocket/websocket_server.h" 18 | 19 | DEFINE_int32(port, 10086, "websocket listening port"); 20 | 21 | int main(int argc, char* argv[]) { 22 | gflags::ParseCommandLineFlags(&argc, &argv, false); 23 | google::InitGoogleLogging(argv[0]); 24 | 25 | auto decode_config = wenet::InitDecodeOptionsFromFlags(); 26 | auto feature_config = wenet::InitFeaturePipelineConfigFromFlags(); 27 | auto decode_resource = wenet::InitDecodeResourceFromFlags(); 28 | 29 | wenet::WebSocketServer server(FLAGS_port, feature_config, decode_config, 30 | decode_resource); 31 | LOG(INFO) << "Listening at port " << FLAGS_port; 32 | server.Start(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/boost.cmake: -------------------------------------------------------------------------------- 1 | FetchContent_Declare(boost 2 | URL https://boostorg.jfrog.io/artifactory/main/release/1.75.0/source/boost_1_75_0.tar.gz 3 | URL_HASH SHA256=aeb26f80e80945e82ee93e5939baebdca47b9dee80a07d3144be1e1a6a66dd6a 4 | ) 5 | FetchContent_MakeAvailable(boost) 6 | include_directories(${boost_SOURCE_DIR}) 7 | 8 | if(MSVC) 9 | add_definitions(-DBOOST_ALL_DYN_LINK -DBOOST_ALL_NO_LIB) 10 | endif() -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/gflags.cmake: -------------------------------------------------------------------------------- 1 | FetchContent_Declare(gflags 2 | URL https://github.com/gflags/gflags/archive/v2.2.2.zip 3 | URL_HASH SHA256=19713a36c9f32b33df59d1c79b4958434cb005b5b47dc5400a7a4b078111d9b5 4 | ) 5 | FetchContent_MakeAvailable(gflags) 6 | include_directories(${gflags_BINARY_DIR}/include) -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/glog.cmake: -------------------------------------------------------------------------------- 1 | FetchContent_Declare(glog 2 | URL https://github.com/google/glog/archive/v0.4.0.zip 3 | URL_HASH SHA256=9e1b54eb2782f53cd8af107ecf08d2ab64b8d0dc2b7f5594472f3bd63ca85cdc 4 | ) 5 | FetchContent_MakeAvailable(glog) 6 | include_directories(${glog_SOURCE_DIR}/src ${glog_BINARY_DIR}) -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/grpc.cmake: -------------------------------------------------------------------------------- 1 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/grpc) 2 | # third_party: grpc 3 | # On how to build grpc, you may refer to https://github.com/grpc/grpc 4 | # We recommend manually recursive clone the repo to avoid internet connection problem 5 | FetchContent_Declare(gRPC 6 | GIT_REPOSITORY https://github.com/grpc/grpc 7 | GIT_TAG v1.37.1 8 | ) 9 | FetchContent_MakeAvailable(gRPC) -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/gtest.cmake: -------------------------------------------------------------------------------- 1 | FetchContent_Declare(googletest 2 | URL https://github.com/google/googletest/archive/release-1.11.0.zip 3 | URL_HASH SHA256=353571c2440176ded91c2de6d6cd88ddd41401d14692ec1f99e35d013feda55a 4 | ) 5 | if(MSVC) 6 | set(gtest_force_shared_crt ON CACHE BOOL "Always use msvcrt.dll" FORCE) 7 | endif() 8 | FetchContent_MakeAvailable(googletest) -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/libtorch.cmake: -------------------------------------------------------------------------------- 1 | if(TORCH) 2 | if(NOT ANDROID) 3 | set(PYTORCH_VERSION "1.10.0") 4 | if(GPU) 5 | add_definitions(-DUSE_GPU) 6 | set(CUDA_NAME "cu113") 7 | endif() 8 | if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") 9 | if(GPU) 10 | message(FATAL_ERROR "GPU on Windows is unsupported, you can use CPU version") 11 | endif() 12 | if(${CMAKE_BUILD_TYPE} MATCHES "Release") 13 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/cpu/libtorch-win-shared-with-deps-${PYTORCH_VERSION}%2Bcpu.zip") 14 | set(URL_HASH "SHA256=d7043b7d7bdb5463e5027c896ac21b83257c32c533427d4d0d7b251548db8f4b") 15 | else() 16 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/cpu/libtorch-win-shared-with-deps-debug-${PYTORCH_VERSION}%2Bcpu.zip") 17 | set(URL_HASH "SHA256=d98c1b6d425ce62a6d65c16d496ef808fb2e7053d706202c536a7e437a5ade86") 18 | endif() 19 | elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 20 | if(CXX11_ABI) 21 | if(NOT GPU) 22 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-${PYTORCH_VERSION}%2Bcpu.zip") 23 | set(URL_HASH "SHA256=6d7be1073d1bd76f6563572b2aa5548ad51d5bc241d6895e3181b7dc25554426") 24 | else() 25 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/${CUDA_NAME}/libtorch-cxx11-abi-shared-with-deps-${PYTORCH_VERSION}%2B${CUDA_NAME}.zip") 26 | set(URL_HASH "SHA256=190e963e739d5f7c2dcf94b3994de8fcd335706a4ebb333812ea7d8c841beb06") 27 | endif() 28 | else() 29 | if(NOT GPU) 30 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/cpu/libtorch-shared-with-deps-${PYTORCH_VERSION}%2Bcpu.zip") 31 | set(URL_HASH "SHA256=16961222938b205a6a767b0b0b9f5e3b1f8740aa1f3475580e33cfd5952b1a44") 32 | else() 33 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/${CUDA_NAME}/libtorch-shared-with-deps-${PYTORCH_VERSION}%2B${CUDA_NAME}.zip") 34 | set(URL_HASH "SHA256=0996a6a4ea8bbc1137b4fb0476eeca25b5efd8ed38955218dec1b73929090053") 35 | endif() 36 | endif() 37 | elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") 38 | if(GPU) 39 | message(FATAL_ERROR "GPU on Darwin is unsupported, you can use CPU version") 40 | endif() 41 | set(LIBTORCH_URL "https://download.pytorch.org/libtorch/cpu/libtorch-macos-${PYTORCH_VERSION}.zip") 42 | set(URL_HASH "SHA256=07cac2c36c34f13065cb9559ad5270109ecbb468252fb0aeccfd89322322a2b5") 43 | else() 44 | message(FATAL_ERROR "Unsupported CMake System Name '${CMAKE_SYSTEM_NAME}' (expected 'Windows', 'Linux' or 'Darwin')") 45 | endif() 46 | 47 | FetchContent_Declare(libtorch 48 | URL ${LIBTORCH_URL} 49 | URL_HASH ${URL_HASH} 50 | ) 51 | FetchContent_MakeAvailable(libtorch) 52 | find_package(Torch REQUIRED PATHS ${libtorch_SOURCE_DIR} NO_DEFAULT_PATH) 53 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS} -DC10_USE_GLOG") 54 | 55 | if(MSVC) 56 | file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll") 57 | file(COPY ${TORCH_DLLS} DESTINATION ${CMAKE_BINARY_DIR}) 58 | endif() 59 | else() 60 | # Change version in runtime/android/app/build.gradle. 61 | file(GLOB PYTORCH_INCLUDE_DIRS "${build_DIR}/pytorch_android*.aar/headers") 62 | file(GLOB PYTORCH_LINK_DIRS "${build_DIR}/pytorch_android*.aar/jni/${ANDROID_ABI}") 63 | find_library(PYTORCH_LIBRARY pytorch_jni 64 | PATHS ${PYTORCH_LINK_DIRS} 65 | NO_CMAKE_FIND_ROOT_PATH 66 | ) 67 | find_library(FBJNI_LIBRARY fbjni 68 | PATHS ${PYTORCH_LINK_DIRS} 69 | NO_CMAKE_FIND_ROOT_PATH 70 | ) 71 | include_directories( 72 | ${PYTORCH_INCLUDE_DIRS} 73 | ${PYTORCH_INCLUDE_DIRS}/torch/csrc/api/include 74 | ) 75 | endif() 76 | add_definitions(-DUSE_TORCH) 77 | endif() 78 | -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/onnx.cmake: -------------------------------------------------------------------------------- 1 | if(ONNX) 2 | set(ONNX_VERSION "1.9.0") 3 | if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") 4 | set(ONNX_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNX_VERSION}/onnxruntime-win-x64-${ONNX_VERSION}.zip") 5 | set(URL_HASH "SHA256=484b08c55867963bd8f74cc39d7c9b6199260f1184839cc40f37e50304597364") 6 | elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 7 | set(ONNX_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNX_VERSION}/onnxruntime-linux-x64-${ONNX_VERSION}.tgz") 8 | set(URL_HASH "SHA256=f386ab80e9d6d41f14ed9e61bff4acc6bf375770691bc3ba883ba0ba3cabca7f") 9 | elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") 10 | set(ONNX_URL "https://github.com/microsoft/onnxruntime/releases/download/v${ONNX_VERSION}/onnxruntime-osx-x64-${ONNX_VERSION}.tgz") 11 | set(URL_HASH "SHA256=71517c8571186eddd31e78134ac441571494fc2f524153165f4a2fec22940d66") 12 | else() 13 | message(FATAL_ERROR "Unsupported CMake System Name '${CMAKE_SYSTEM_NAME}' (expected 'Windows', 'Linux' or 'Darwin')") 14 | endif() 15 | 16 | FetchContent_Declare(onnxruntime 17 | URL ${ONNX_URL} 18 | URL_HASH ${URL_HASH} 19 | ) 20 | FetchContent_MakeAvailable(onnxruntime) 21 | include_directories(${onnxruntime_SOURCE_DIR}/include) 22 | link_directories(${onnxruntime_SOURCE_DIR}/lib) 23 | 24 | if(MSVC) 25 | file(GLOB ONNX_DLLS "${onnxruntime_SOURCE_DIR}/lib/*.dll") 26 | file(COPY ${ONNX_DLLS} DESTINATION ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE}) 27 | endif() 28 | 29 | add_definitions(-DUSE_ONNX) 30 | endif() 31 | -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/openfst.cmake: -------------------------------------------------------------------------------- 1 | if(NOT ANDROID) 2 | include(gflags) 3 | include(glog) 4 | 5 | set(CONFIG_FLAGS "") 6 | if(NOT FST_HAVE_BIN) 7 | if(MSVC) 8 | set(HAVE_BIN OFF CACHE BOOL "Build the fst binaries" FORCE) 9 | else() 10 | set(CONFIG_FLAGS "--disable-bin") 11 | endif() 12 | endif() 13 | 14 | if(MSVC) 15 | set(HAVE_SCRIPT OFF CACHE BOOL "Build the fstscript" FORCE) 16 | set(HAVE_COMPACT OFF CACHE BOOL "Build compact" FORCE) 17 | set(HAVE_CONST OFF CACHE BOOL "Build const" FORCE) 18 | set(HAVE_GRM OFF CACHE BOOL "Build grm" FORCE) 19 | set(HAVE_PDT OFF CACHE BOOL "Build pdt" FORCE) 20 | set(HAVE_MPDT OFF CACHE BOOL "Build mpdt" FORCE) 21 | set(HAVE_LINEAR OFF CACHE BOOL "Build linear" FORCE) 22 | set(HAVE_LOOKAHEAD OFF CACHE BOOL "Build lookahead" FORCE) 23 | set(HAVE_NGRAM OFF CACHE BOOL "Build ngram" FORCE) 24 | set(HAVE_SPECIAL OFF CACHE BOOL "Build special" FORCE) 25 | endif() 26 | 27 | # The original openfst uses GNU Build System to run configure and build. 28 | # So, we use "OpenFST port for Windows" to build openfst with cmake in Windows. 29 | # Openfst is compiled with glog/gflags to avoid log and flag conflicts with log and flags in wenet/libtorch. 30 | # To build openfst with gflags and glog, we comment out some vars of {flags, log}.h and flags.cc. 31 | set(openfst_SOURCE_DIR ${fc_base}/openfst-src CACHE PATH "OpenFST source directory") 32 | set(openfst_BINARY_DIR ${fc_base}/openfst-build CACHE PATH "OpenFST build directory") 33 | set(openfst_PREFIX_DIR ${fc_base}/openfst-subbuild/openfst-populate-prefix CACHE PATH "OpenFST prefix directory") 34 | if(NOT MSVC) 35 | ExternalProject_Add(openfst 36 | URL https://github.com/mjansche/openfst/archive/1.6.5.zip 37 | URL_HASH SHA256=b720357a464f42e181d7e33f60867b54044007f50baedc8f4458a3926f4a5a78 38 | PREFIX ${openfst_PREFIX_DIR} 39 | SOURCE_DIR ${openfst_SOURCE_DIR} 40 | BINARY_DIR ${openfst_BINARY_DIR} 41 | CONFIGURE_COMMAND ${openfst_SOURCE_DIR}/configure ${CONFIG_FLAGS} --prefix=${openfst_PREFIX_DIR} 42 | "CPPFLAGS=-I${gflags_BINARY_DIR}/include -I${glog_SOURCE_DIR}/src -I${glog_BINARY_DIR} ${TORCH_CXX_FLAGS}" 43 | "LDFLAGS=-L${gflags_BINARY_DIR} -L${glog_BINARY_DIR}" 44 | "LIBS=-lgflags_nothreads -lglog -lpthread" 45 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/patch/openfst ${openfst_SOURCE_DIR} 46 | BUILD_COMMAND make -j$(nproc) 47 | ) 48 | add_dependencies(openfst gflags glog) 49 | link_directories(${openfst_PREFIX_DIR}/lib) 50 | else() 51 | add_compile_options(/W0 /wd4244 /wd4267) 52 | FetchContent_Declare(openfst 53 | URL https://github.com/kkm000/openfst/archive/refs/tags/win/1.6.5.1.tar.gz 54 | URL_HASH SHA256=02c49b559c3976a536876063369efc0e41ab374be1035918036474343877046e 55 | PATCH_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/patch/openfst ${openfst_SOURCE_DIR} 56 | ) 57 | FetchContent_MakeAvailable(openfst) 58 | add_dependencies(fst gflags glog) 59 | target_link_libraries(fst PUBLIC gflags_nothreads_static glog) 60 | endif() 61 | include_directories(${openfst_SOURCE_DIR}/src/include) 62 | else() 63 | set(openfst_BINARY_DIR ${build_DIR}/wenet-openfst-android-1.0.2.aar/jni) 64 | include_directories(${openfst_BINARY_DIR}/include) 65 | link_directories(${openfst_BINARY_DIR}/${ANDROID_ABI}) 66 | link_libraries(log gflags_nothreads glog fst) 67 | endif() 68 | -------------------------------------------------------------------------------- /android/src/main/cpp/cmake/pybind11.cmake: -------------------------------------------------------------------------------- 1 | FetchContent_Declare(pybind11 2 | URL https://github.com/pybind/pybind11/archive/refs/tags/v2.9.2.zip 3 | URL_HASH SHA256=d1646e6f70d8a3acb2ddd85ce1ed543b5dd579c68b8fb8e9638282af20edead8 4 | ) 5 | FetchContent_MakeAvailable(pybind11) 6 | 7 | add_subdirectory(${pybind11_SOURCE_DIR}) -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(decoder_srcs 2 | asr_decoder.cc 3 | asr_model.cc 4 | context_graph.cc 5 | ctc_prefix_beam_search.cc 6 | ctc_wfst_beam_search.cc 7 | ctc_endpoint.cc 8 | ) 9 | 10 | if(NOT TORCH AND NOT ONNX) 11 | message(FATAL_ERROR "Please build with TORCH or ONNX!!!") 12 | endif() 13 | if(TORCH) 14 | list(APPEND decoder_srcs torch_asr_model.cc) 15 | endif() 16 | if(ONNX) 17 | list(APPEND decoder_srcs onnx_asr_model.cc) 18 | endif() 19 | 20 | add_library(decoder STATIC ${decoder_srcs}) 21 | target_link_libraries(decoder PUBLIC kaldi-decoder frontend post_processor utils) 22 | 23 | if(ANDROID) 24 | target_link_libraries(decoder PUBLIC ${PYTORCH_LIBRARY} ${FBJNI_LIBRARY}) 25 | else() 26 | if(TORCH) 27 | target_link_libraries(decoder PUBLIC ${TORCH_LIBRARIES}) 28 | endif() 29 | if(ONNX) 30 | target_link_libraries(decoder PUBLIC onnxruntime) 31 | endif() 32 | endif() 33 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/asr_model.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Horizon Robotics. All Rights Reserved. 2 | // Author: binbin.zhang@horizon.ai (Binbin Zhang) 3 | 4 | #include "decoder/asr_model.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace wenet { 10 | 11 | int AsrModel::num_frames_for_chunk(bool start) const { 12 | int num_required_frames = 0; 13 | if (chunk_size_ > 0) { 14 | if (!start) { // First batch 15 | int context = right_context_ + 1; // Add current frame 16 | num_required_frames = (chunk_size_ - 1) * subsampling_rate_ + context; 17 | } else { 18 | num_required_frames = chunk_size_ * subsampling_rate_; 19 | } 20 | } else { 21 | num_required_frames = std::numeric_limits::max(); 22 | } 23 | return num_required_frames; 24 | } 25 | 26 | void AsrModel::CacheFeature( 27 | const std::vector>& chunk_feats) { 28 | // Cache feature for next chunk 29 | const int cached_feature_size = 1 + right_context_ - subsampling_rate_; 30 | if (chunk_feats.size() >= cached_feature_size) { 31 | // TODO(Binbin Zhang): Only deal the case when 32 | // chunk_feats.size() > cached_feature_size here, and it's consistent 33 | // with our current model, refine it later if we have new model or 34 | // new requirements 35 | cached_feature_.resize(cached_feature_size); 36 | for (int i = 0; i < cached_feature_size; ++i) { 37 | cached_feature_[i] = 38 | chunk_feats[chunk_feats.size() - cached_feature_size + i]; 39 | } 40 | } 41 | } 42 | 43 | void AsrModel::ForwardEncoder( 44 | const std::vector>& chunk_feats, 45 | std::vector>* ctc_prob) { 46 | ctc_prob->clear(); 47 | int num_frames = cached_feature_.size() + chunk_feats.size(); 48 | if (num_frames >= right_context_ + 1) { 49 | this->ForwardEncoderFunc(chunk_feats, ctc_prob); 50 | this->CacheFeature(chunk_feats); 51 | } 52 | } 53 | 54 | } // namespace wenet 55 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/asr_model.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Horizon Robotics. All Rights Reserved. 2 | // Author: binbin.zhang@horizon.ai (Binbin Zhang) 3 | 4 | #ifndef DECODER_ASR_MODEL_H_ 5 | #define DECODER_ASR_MODEL_H_ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "utils/timer.h" 13 | #include "utils/utils.h" 14 | 15 | namespace wenet { 16 | 17 | class AsrModel { 18 | public: 19 | virtual int right_context() const { return right_context_; } 20 | virtual int subsampling_rate() const { return subsampling_rate_; } 21 | virtual int sos() const { return sos_; } 22 | virtual int eos() const { return eos_; } 23 | virtual bool is_bidirectional_decoder() const { 24 | return is_bidirectional_decoder_; 25 | } 26 | virtual int offset() const { return offset_; } 27 | 28 | // If chunk_size > 0, streaming case. Otherwise, none streaming case 29 | virtual void set_chunk_size(int chunk_size) { chunk_size_ = chunk_size; } 30 | virtual void set_num_left_chunks(int num_left_chunks) { 31 | num_left_chunks_ = num_left_chunks; 32 | } 33 | // start: if it is the start chunk of one sentence 34 | virtual int num_frames_for_chunk(bool start) const; 35 | 36 | virtual void Reset() = 0; 37 | 38 | virtual void ForwardEncoder( 39 | const std::vector>& chunk_feats, 40 | std::vector>* ctc_prob); 41 | 42 | virtual void AttentionRescoring(const std::vector>& hyps, 43 | float reverse_weight, 44 | std::vector* rescoring_score) = 0; 45 | 46 | virtual std::shared_ptr Copy() const = 0; 47 | 48 | protected: 49 | virtual void ForwardEncoderFunc( 50 | const std::vector>& chunk_feats, 51 | std::vector>* ctc_prob) = 0; 52 | virtual void CacheFeature(const std::vector>& chunk_feats); 53 | 54 | int right_context_ = 1; 55 | int subsampling_rate_ = 1; 56 | int sos_ = 0; 57 | int eos_ = 0; 58 | bool is_bidirectional_decoder_ = false; 59 | int chunk_size_ = 16; 60 | int num_left_chunks_ = -1; // -1 means all left chunks 61 | int offset_ = 0; 62 | 63 | std::vector> cached_feature_; 64 | }; 65 | 66 | } // namespace wenet 67 | 68 | #endif // DECODER_ASR_MODEL_H_ 69 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/context_graph.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Zhendong Peng) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef DECODER_CONTEXT_GRAPH_H_ 17 | #define DECODER_CONTEXT_GRAPH_H_ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "fst/compose.h" 24 | #include "fst/fst.h" 25 | #include "fst/vector-fst.h" 26 | 27 | namespace wenet { 28 | 29 | using StateId = fst::StdArc::StateId; 30 | 31 | struct ContextConfig { 32 | int max_contexts = 5000; 33 | int max_context_length = 100; 34 | float context_score = 3.0; 35 | float incremental_context_score = 0.0; 36 | }; 37 | 38 | class ContextGraph { 39 | public: 40 | explicit ContextGraph(ContextConfig config); 41 | void BuildContextGraph(const std::vector& query_context, 42 | const std::shared_ptr& symbol_table); 43 | int GetNextState(int cur_state, int word_id, float* score, 44 | bool* is_start_boundary, bool* is_end_boundary); 45 | 46 | int start_tag_id() { return start_tag_id_; } 47 | int end_tag_id() { return end_tag_id_; } 48 | 49 | private: 50 | int start_tag_id_ = -1; 51 | int end_tag_id_ = -1; 52 | ContextConfig config_; 53 | std::shared_ptr symbol_table_ = nullptr; 54 | std::unique_ptr graph_ = nullptr; 55 | DISALLOW_COPY_AND_ASSIGN(ContextGraph); 56 | }; 57 | 58 | } // namespace wenet 59 | 60 | #endif // DECODER_CONTEXT_GRAPH_H_ 61 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/ctc_endpoint.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Zhendong Peng) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include "decoder/ctc_endpoint.h" 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include "utils/log.h" 24 | 25 | namespace wenet { 26 | 27 | CtcEndpoint::CtcEndpoint(const CtcEndpointConfig& config) : config_(config) { 28 | Reset(); 29 | } 30 | 31 | void CtcEndpoint::Reset() { 32 | num_frames_decoded_ = 0; 33 | num_frames_trailing_blank_ = 0; 34 | } 35 | 36 | static bool RuleActivated(const CtcEndpointRule& rule, 37 | const std::string& rule_name, bool decoded_sth, 38 | int trailing_silence, int utterance_length) { 39 | bool ans = (decoded_sth || !rule.must_decoded_sth) && 40 | trailing_silence >= rule.min_trailing_silence && 41 | utterance_length >= rule.min_utterance_length; 42 | if (ans) { 43 | VLOG(2) << "Endpointing rule " << rule_name 44 | << " activated: " << (decoded_sth ? "true" : "false") << ',' 45 | << trailing_silence << ',' << utterance_length; 46 | } 47 | return ans; 48 | } 49 | 50 | bool CtcEndpoint::IsEndpoint( 51 | const std::vector>& ctc_log_probs, 52 | bool decoded_something) { 53 | for (int t = 0; t < ctc_log_probs.size(); ++t) { 54 | const auto& logp_t = ctc_log_probs[t]; 55 | float blank_prob = expf(logp_t[config_.blank]); 56 | 57 | num_frames_decoded_++; 58 | if (blank_prob > config_.blank_threshold) { 59 | num_frames_trailing_blank_++; 60 | } else { 61 | num_frames_trailing_blank_ = 0; 62 | } 63 | } 64 | CHECK_GE(num_frames_decoded_, num_frames_trailing_blank_); 65 | CHECK_GT(frame_shift_in_ms_, 0); 66 | int utterance_length = num_frames_decoded_ * frame_shift_in_ms_; 67 | int trailing_silence = num_frames_trailing_blank_ * frame_shift_in_ms_; 68 | if (RuleActivated(config_.rule1, "rule1", decoded_something, trailing_silence, 69 | utterance_length)) 70 | return true; 71 | if (RuleActivated(config_.rule2, "rule2", decoded_something, trailing_silence, 72 | utterance_length)) 73 | return true; 74 | if (RuleActivated(config_.rule3, "rule3", decoded_something, trailing_silence, 75 | utterance_length)) 76 | return true; 77 | return false; 78 | } 79 | 80 | } // namespace wenet 81 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/ctc_endpoint.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Zhendong Peng) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef DECODER_CTC_ENDPOINT_H_ 17 | #define DECODER_CTC_ENDPOINT_H_ 18 | 19 | #include 20 | 21 | namespace wenet { 22 | 23 | struct CtcEndpointRule { 24 | bool must_decoded_sth; 25 | int min_trailing_silence; 26 | int min_utterance_length; 27 | 28 | CtcEndpointRule(bool must_decoded_sth = true, int min_trailing_silence = 1000, 29 | int min_utterance_length = 0) 30 | : must_decoded_sth(must_decoded_sth), 31 | min_trailing_silence(min_trailing_silence), 32 | min_utterance_length(min_utterance_length) {} 33 | }; 34 | 35 | struct CtcEndpointConfig { 36 | /// We consider blank as silence for purposes of endpointing. 37 | int blank = 0; // blank id 38 | float blank_threshold = 0.8; // blank threshold to be silence 39 | /// We support three rules. We terminate decoding if ANY of these rules 40 | /// evaluates to "true". If you want to add more rules, do it by changing this 41 | /// code. If you want to disable a rule, you can set the silence-timeout for 42 | /// that rule to a very large number. 43 | 44 | /// rule1 times out after 5000 ms of silence, even if we decoded nothing. 45 | CtcEndpointRule rule1; 46 | /// rule2 times out after 1000 ms of silence after decoding something. 47 | CtcEndpointRule rule2; 48 | /// rule3 times out after the utterance is 20000 ms long, regardless of 49 | /// anything else. 50 | CtcEndpointRule rule3; 51 | 52 | CtcEndpointConfig() 53 | : rule1(false, 5000, 0), rule2(true, 1000, 0), rule3(false, 0, 20000) {} 54 | }; 55 | 56 | class CtcEndpoint { 57 | public: 58 | explicit CtcEndpoint(const CtcEndpointConfig& config); 59 | 60 | void Reset(); 61 | /// This function returns true if this set of endpointing rules thinks we 62 | /// should terminate decoding. 63 | bool IsEndpoint(const std::vector>& ctc_log_probs, 64 | bool decoded_something); 65 | 66 | void frame_shift_in_ms(int frame_shift_in_ms) { 67 | frame_shift_in_ms_ = frame_shift_in_ms; 68 | } 69 | 70 | private: 71 | CtcEndpointConfig config_; 72 | int frame_shift_in_ms_ = -1; 73 | int num_frames_decoded_ = 0; 74 | int num_frames_trailing_blank_ = 0; 75 | }; 76 | 77 | } // namespace wenet 78 | 79 | #endif // DECODER_CTC_ENDPOINT_H_ 80 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/ctc_wfst_beam_search.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef DECODER_CTC_WFST_BEAM_SEARCH_H_ 17 | #define DECODER_CTC_WFST_BEAM_SEARCH_H_ 18 | 19 | #include 20 | #include 21 | 22 | #include "decoder/context_graph.h" 23 | #include "decoder/search_interface.h" 24 | #include "kaldi/decoder/lattice-faster-online-decoder.h" 25 | #include "utils/utils.h" 26 | 27 | namespace wenet { 28 | 29 | class DecodableTensorScaled : public kaldi::DecodableInterface { 30 | public: 31 | explicit DecodableTensorScaled(float scale = 1.0) : scale_(scale) { Reset(); } 32 | 33 | void Reset(); 34 | int32 NumFramesReady() const override { return num_frames_ready_; } 35 | bool IsLastFrame(int32 frame) const override; 36 | float LogLikelihood(int32 frame, int32 index) override; 37 | int32 NumIndices() const override; 38 | void AcceptLoglikes(const std::vector& logp); 39 | void SetFinish() { done_ = true; } 40 | 41 | private: 42 | int num_frames_ready_ = 0; 43 | float scale_ = 1.0; 44 | bool done_ = false; 45 | std::vector logp_; 46 | }; 47 | 48 | // LatticeFasterDecoderConfig has the following key members 49 | // beam: decoding beam 50 | // max_active: Decoder max active states 51 | // lattice_beam: Lattice generation beam 52 | struct CtcWfstBeamSearchOptions : public kaldi::LatticeFasterDecoderConfig { 53 | float acoustic_scale = 1.0; 54 | float nbest = 10; 55 | // When blank score is greater than this thresh, skip the frame in viterbi 56 | // search 57 | float blank_skip_thresh = 0.98; 58 | }; 59 | 60 | class CtcWfstBeamSearch : public SearchInterface { 61 | public: 62 | explicit CtcWfstBeamSearch( 63 | const fst::Fst& fst, const CtcWfstBeamSearchOptions& opts, 64 | const std::shared_ptr& context_graph); 65 | void Search(const std::vector>& logp) override; 66 | void Reset() override; 67 | void FinalizeSearch() override; 68 | SearchType Type() const override { return SearchType::kWfstBeamSearch; } 69 | // For CTC prefix beam search, both inputs and outputs are hypotheses_ 70 | const std::vector>& Inputs() const override { 71 | return inputs_; 72 | } 73 | const std::vector>& Outputs() const override { 74 | return outputs_; 75 | } 76 | const std::vector& Likelihood() const override { return likelihood_; } 77 | const std::vector>& Times() const override { return times_; } 78 | 79 | private: 80 | // Sub one and remove 81 | void ConvertToInputs(const std::vector& alignment, 82 | std::vector* input, 83 | std::vector* time = nullptr); 84 | void RemoveContinuousTags(std::vector* output); 85 | 86 | int num_frames_ = 0; 87 | std::vector decoded_frames_mapping_; 88 | 89 | int last_best_ = 0; // last none blank best id 90 | std::vector last_frame_prob_; 91 | bool is_last_frame_blank_ = false; 92 | std::vector> inputs_, outputs_; 93 | std::vector likelihood_; 94 | std::vector> times_; 95 | DecodableTensorScaled decodable_; 96 | kaldi::LatticeFasterOnlineDecoder decoder_; 97 | std::shared_ptr context_graph_; 98 | const CtcWfstBeamSearchOptions& opts_; 99 | }; 100 | 101 | } // namespace wenet 102 | 103 | #endif // DECODER_CTC_WFST_BEAM_SEARCH_H_ 104 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/onnx_asr_model.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang, Di Wu) 2 | // 2022 ZeXuan Li (lizexuan@huya.com) 3 | // Xingchen Song(sxc19@mails.tsinghua.edu.cn) 4 | // hamddct@gmail.com (Mddct) 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | 19 | #ifndef DECODER_ONNX_ASR_MODEL_H_ 20 | #define DECODER_ONNX_ASR_MODEL_H_ 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "onnxruntime_cxx_api.h" // NOLINT 27 | 28 | #include "decoder/asr_model.h" 29 | #include "utils/log.h" 30 | #include "utils/utils.h" 31 | 32 | namespace wenet { 33 | 34 | class OnnxAsrModel : public AsrModel { 35 | public: 36 | // Note: Do not call the InitEngineThreads function more than once. 37 | static void InitEngineThreads(int num_threads = 1); 38 | 39 | public: 40 | OnnxAsrModel() = default; 41 | OnnxAsrModel(const OnnxAsrModel& other); 42 | void Read(const std::string& model_dir); 43 | void Reset() override; 44 | void AttentionRescoring(const std::vector>& hyps, 45 | float reverse_weight, 46 | std::vector* rescoring_score) override; 47 | std::shared_ptr Copy() const override; 48 | void GetInputOutputInfo(const std::shared_ptr& session, 49 | std::vector* in_names, 50 | std::vector* out_names); 51 | 52 | protected: 53 | void ForwardEncoderFunc(const std::vector>& chunk_feats, 54 | std::vector>* ctc_prob) override; 55 | 56 | float ComputeAttentionScore(const float* prob, const std::vector& hyp, 57 | int eos, int decode_out_len); 58 | 59 | private: 60 | int encoder_output_size_ = 0; 61 | int num_blocks_ = 0; 62 | int cnn_module_kernel_ = 0; 63 | int head_ = 0; 64 | 65 | // sessions 66 | // NOTE(Mddct): The Env holds the logging state used by all other objects. 67 | // One Env must be created before using any other Onnxruntime functionality. 68 | static Ort::Env env_; // shared environment across threads. 69 | static Ort::SessionOptions session_options_; 70 | std::shared_ptr encoder_session_ = nullptr; 71 | std::shared_ptr rescore_session_ = nullptr; 72 | std::shared_ptr ctc_session_ = nullptr; 73 | 74 | // node names 75 | std::vector encoder_in_names_, encoder_out_names_; 76 | std::vector ctc_in_names_, ctc_out_names_; 77 | std::vector rescore_in_names_, rescore_out_names_; 78 | 79 | // caches 80 | Ort::Value att_cache_ort_{nullptr}; 81 | Ort::Value cnn_cache_ort_{nullptr}; 82 | std::vector encoder_outs_; 83 | // NOTE: Instead of making a copy of the xx_cache, ONNX only maintains 84 | // its data pointer when initializing xx_cache_ort (see https://github.com/ 85 | // microsoft/onnxruntime/blob/master/onnxruntime/core/framework 86 | // /tensor.cc#L102-L129), so we need the following variables to keep 87 | // our data "alive" during the lifetime of decoder. 88 | std::vector att_cache_; 89 | std::vector cnn_cache_; 90 | }; 91 | 92 | } // namespace wenet 93 | 94 | #endif // DECODER_ONNX_ASR_MODEL_H_ 95 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/search_interface.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef DECODER_SEARCH_INTERFACE_H_ 17 | #define DECODER_SEARCH_INTERFACE_H_ 18 | 19 | namespace wenet { 20 | 21 | #include 22 | 23 | enum SearchType { 24 | kPrefixBeamSearch = 0x00, 25 | kWfstBeamSearch = 0x01, 26 | }; 27 | 28 | class SearchInterface { 29 | public: 30 | virtual ~SearchInterface() {} 31 | virtual void Search(const std::vector>& logp) = 0; 32 | virtual void Reset() = 0; 33 | virtual void FinalizeSearch() = 0; 34 | 35 | virtual SearchType Type() const = 0; 36 | // N-best inputs id 37 | virtual const std::vector>& Inputs() const = 0; 38 | // N-best outputs id 39 | virtual const std::vector>& Outputs() const = 0; 40 | // N-best likelihood 41 | virtual const std::vector& Likelihood() const = 0; 42 | // N-best timestamp 43 | virtual const std::vector>& Times() const = 0; 44 | }; 45 | 46 | } // namespace wenet 47 | 48 | #endif // DECODER_SEARCH_INTERFACE_H_ 49 | -------------------------------------------------------------------------------- /android/src/main/cpp/decoder/torch_asr_model.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang, Di Wu) 2 | // 2022 Binbin Zhang (binbzha@qq.com) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | 17 | #ifndef DECODER_TORCH_ASR_MODEL_H_ 18 | #define DECODER_TORCH_ASR_MODEL_H_ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "torch/script.h" 25 | #include "torch/torch.h" 26 | 27 | #include "decoder/asr_model.h" 28 | #include "utils/utils.h" 29 | 30 | namespace wenet { 31 | 32 | class TorchAsrModel : public AsrModel { 33 | public: 34 | // Note: Do not call the InitEngineThreads function more than once. 35 | static void InitEngineThreads(int num_threads = 1); 36 | 37 | public: 38 | using TorchModule = torch::jit::script::Module; 39 | TorchAsrModel() = default; 40 | TorchAsrModel(const TorchAsrModel& other); 41 | void Read(const std::string& model_path); 42 | std::shared_ptr torch_model() const { return model_; } 43 | void Reset() override; 44 | void AttentionRescoring(const std::vector>& hyps, 45 | float reverse_weight, 46 | std::vector* rescoring_score) override; 47 | std::shared_ptr Copy() const override; 48 | 49 | protected: 50 | void ForwardEncoderFunc(const std::vector>& chunk_feats, 51 | std::vector>* ctc_prob) override; 52 | 53 | float ComputeAttentionScore(const torch::Tensor& prob, 54 | const std::vector& hyp, int eos); 55 | 56 | private: 57 | std::shared_ptr model_ = nullptr; 58 | std::vector encoder_outs_; 59 | // transformer/conformer attention cache 60 | torch::Tensor att_cache_ = torch::zeros({0, 0, 0, 0}); 61 | // conformer-only conv_module cache 62 | torch::Tensor cnn_cache_ = torch::zeros({0, 0, 0, 0}); 63 | }; 64 | 65 | } // namespace wenet 66 | 67 | #endif // DECODER_TORCH_ASR_MODEL_H_ 68 | -------------------------------------------------------------------------------- /android/src/main/cpp/frontend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(frontend STATIC 2 | feature_pipeline.cc 3 | fft.cc 4 | ) 5 | target_link_libraries(frontend PUBLIC utils) -------------------------------------------------------------------------------- /android/src/main/cpp/frontend/fft.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Network 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "frontend/fft.h" 21 | 22 | namespace wenet { 23 | 24 | void make_sintbl(int n, float* sintbl) { 25 | int i, n2, n4, n8; 26 | float c, s, dc, ds, t; 27 | 28 | n2 = n / 2; 29 | n4 = n / 4; 30 | n8 = n / 8; 31 | t = sin(M_PI / n); 32 | dc = 2 * t * t; 33 | ds = sqrt(dc * (2 - dc)); 34 | t = 2 * dc; 35 | c = sintbl[n4] = 1; 36 | s = sintbl[0] = 0; 37 | for (i = 1; i < n8; ++i) { 38 | c -= dc; 39 | dc += t * c; 40 | s += ds; 41 | ds -= t * s; 42 | sintbl[i] = s; 43 | sintbl[n4 - i] = c; 44 | } 45 | if (n8 != 0) sintbl[n8] = sqrt(0.5); 46 | for (i = 0; i < n4; ++i) sintbl[n2 - i] = sintbl[i]; 47 | for (i = 0; i < n2 + n4; ++i) sintbl[i + n2] = -sintbl[i]; 48 | } 49 | 50 | void make_bitrev(int n, int* bitrev) { 51 | int i, j, k, n2; 52 | 53 | n2 = n / 2; 54 | i = j = 0; 55 | for (;;) { 56 | bitrev[i] = j; 57 | if (++i >= n) break; 58 | k = n2; 59 | while (k <= j) { 60 | j -= k; 61 | k /= 2; 62 | } 63 | j += k; 64 | } 65 | } 66 | 67 | // bitrev: bit reversal table 68 | // sintbl: trigonometric function table 69 | // x:real part 70 | // y:image part 71 | // n: fft length 72 | int fft(const int* bitrev, const float* sintbl, float* x, float* y, int n) { 73 | int i, j, k, ik, h, d, k2, n4, inverse; 74 | float t, s, c, dx, dy; 75 | 76 | /* preparation */ 77 | if (n < 0) { 78 | n = -n; 79 | inverse = 1; /* inverse transform */ 80 | } else { 81 | inverse = 0; 82 | } 83 | n4 = n / 4; 84 | if (n == 0) { 85 | return 0; 86 | } 87 | 88 | /* bit reversal */ 89 | for (i = 0; i < n; ++i) { 90 | j = bitrev[i]; 91 | if (i < j) { 92 | t = x[i]; 93 | x[i] = x[j]; 94 | x[j] = t; 95 | t = y[i]; 96 | y[i] = y[j]; 97 | y[j] = t; 98 | } 99 | } 100 | 101 | /* transformation */ 102 | for (k = 1; k < n; k = k2) { 103 | h = 0; 104 | k2 = k + k; 105 | d = n / k2; 106 | for (j = 0; j < k; ++j) { 107 | c = sintbl[h + n4]; 108 | if (inverse) 109 | s = -sintbl[h]; 110 | else 111 | s = sintbl[h]; 112 | for (i = j; i < n; i += k2) { 113 | ik = i + k; 114 | dx = s * y[ik] + c * x[ik]; 115 | dy = c * y[ik] - s * x[ik]; 116 | x[ik] = x[i] - dx; 117 | x[i] += dx; 118 | y[ik] = y[i] - dy; 119 | y[i] += dy; 120 | } 121 | h += d; 122 | } 123 | } 124 | if (inverse) { 125 | /* divide by n in case of the inverse transformation */ 126 | for (i = 0; i < n; ++i) { 127 | x[i] /= n; 128 | y[i] /= n; 129 | } 130 | } 131 | return 0; /* finished successfully */ 132 | } 133 | 134 | } // namespace wenet 135 | -------------------------------------------------------------------------------- /android/src/main/cpp/frontend/fft.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Network 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #ifndef FRONTEND_FFT_H_ 17 | #define FRONTEND_FFT_H_ 18 | 19 | #ifndef M_PI 20 | #define M_PI 3.1415926535897932384626433832795 21 | #endif 22 | #ifndef M_2PI 23 | #define M_2PI 6.283185307179586476925286766559005 24 | #endif 25 | 26 | namespace wenet { 27 | 28 | // Fast Fourier Transform 29 | 30 | void make_sintbl(int n, float* sintbl); 31 | 32 | void make_bitrev(int n, int* bitrev); 33 | 34 | int fft(const int* bitrev, const float* sintbl, float* x, float* y, int n); 35 | 36 | } // namespace wenet 37 | 38 | #endif // FRONTEND_FFT_H_ 39 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10 FATAL_ERROR) 2 | 3 | project(kaldi) 4 | 5 | # include_directories() is called in the root CMakeLists.txt 6 | 7 | add_library(kaldi-base 8 | base/kaldi-error.cc 9 | base/kaldi-math.cc 10 | ) 11 | target_link_libraries(kaldi-base PUBLIC utils) 12 | 13 | add_library(kaldi-util 14 | util/kaldi-io.cc 15 | util/parse-options.cc 16 | util/simple-io-funcs.cc 17 | util/text-utils.cc 18 | ) 19 | target_link_libraries(kaldi-util PUBLIC kaldi-base) 20 | 21 | add_library(kaldi-lat 22 | lat/determinize-lattice-pruned.cc 23 | lat/lattice-functions.cc 24 | ) 25 | target_link_libraries(kaldi-lat PUBLIC kaldi-util) 26 | 27 | add_library(kaldi-decoder 28 | decoder/lattice-faster-decoder.cc 29 | decoder/lattice-faster-online-decoder.cc 30 | ) 31 | target_link_libraries(kaldi-decoder PUBLIC kaldi-lat) 32 | 33 | add_library(kaldi-lm 34 | lm/arpa-file-parser.cc 35 | lm/arpa-lm-compiler.cc 36 | ) 37 | target_link_libraries(kaldi-lm PUBLIC kaldi-util) 38 | 39 | add_library(kaldi-fstext 40 | fstext/kaldi-fst-io.cc 41 | ) 42 | target_link_libraries(kaldi-fstext PUBLIC kaldi-util) 43 | 44 | # Arpa binary 45 | add_executable(arpa2fst lmbin/arpa2fst.cc) 46 | target_link_libraries(arpa2fst PUBLIC kaldi-lm) 47 | 48 | # FST tools binary 49 | set(FST_BINS 50 | fstaddselfloops 51 | fstdeterminizestar 52 | fstisstochastic 53 | fstminimizeencoded 54 | fsttablecompose 55 | ) 56 | 57 | if(NOT MSVC) 58 | # dl is for dynamic linking, otherwise there is a linking error on linux 59 | link_libraries(dl) 60 | endif() 61 | foreach(name IN LISTS FST_BINS) 62 | add_executable(${name} fstbin/${name}.cc) 63 | target_link_libraries(${name} PUBLIC kaldi-fstext) 64 | endforeach() 65 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/README.md: -------------------------------------------------------------------------------- 1 | We use Kaldi decoder to implement TLG based language model integration, 2 | so we copied related files to this directory. 3 | The main changes are: 4 | 5 | 1. To minimize the change, we use the same directories tree as Kaldi. 6 | 7 | 2. We replace Kaldi log system with glog in the following way. 8 | 9 | ``` c++ 10 | #define KALDI_WARN \ 11 | google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING).stream() 12 | #define KALDI_ERR \ 13 | google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR).stream() 14 | #define KALDI_INFO \ 15 | google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO).stream() 16 | #define KALDI_VLOG(v) VLOG(v) 17 | 18 | #define KALDI_ASSERT(condition) CHECK(condition) 19 | ``` 20 | 21 | 3. We lint all the files to satisfy the lint in WeNet. 22 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/base/kaldi-common.h: -------------------------------------------------------------------------------- 1 | // base/kaldi-common.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #ifndef KALDI_BASE_KALDI_COMMON_H_ 21 | #define KALDI_BASE_KALDI_COMMON_H_ 1 22 | 23 | #include 24 | #include 25 | #include // C string stuff like strcpy 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "base/kaldi-utils.h" 35 | #include "base/kaldi-error.h" 36 | #include "base/kaldi-types.h" 37 | // #include "base/io-funcs.h" 38 | #include "base/kaldi-math.h" 39 | // #include "base/timer.h" 40 | 41 | #endif // KALDI_BASE_KALDI_COMMON_H_ 42 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/base/kaldi-error.cc: -------------------------------------------------------------------------------- 1 | // base/kaldi-error.cc 2 | 3 | // Copyright 2019 LAIX (Yi Sun) 4 | // Copyright 2019 SmartAction LLC (kkm) 5 | // Copyright 2016 Brno University of Technology (author: Karel Vesely) 6 | // Copyright 2009-2011 Microsoft Corporation; Lukas Burget; Ondrej Glembek 7 | 8 | // See ../../COPYING for clarification regarding multiple authors 9 | // 10 | // Licensed under the Apache License, Version 2.0 (the "License"); 11 | // you may not use this file except in compliance with the License. 12 | // You may obtain a copy of the License at 13 | // 14 | // http://www.apache.org/licenses/LICENSE-2.0 15 | // 16 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 18 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 19 | // MERCHANTABLITY OR NON-INFRINGEMENT. 20 | // See the Apache 2 License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #include "base/kaldi-error.h" 24 | 25 | #include 26 | 27 | namespace kaldi { 28 | 29 | /***** GLOBAL VARIABLES FOR LOGGING *****/ 30 | 31 | int32 g_kaldi_verbose_level = 0; 32 | static std::string program_name; // NOLINT 33 | 34 | void SetProgramName(const char *basename) { 35 | // Using the 'static std::string' for the program name is mostly harmless, 36 | // because (a) Kaldi logging is undefined before main(), and (b) no stdc++ 37 | // string implementation has been found in the wild that would not be just 38 | // an empty string when zero-initialized but not yet constructed. 39 | program_name = basename; 40 | } 41 | 42 | } // namespace kaldi 43 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/base/kaldi-error.h: -------------------------------------------------------------------------------- 1 | // base/kaldi-error.h 2 | 3 | // Copyright (c) 2021 Mobvoi Inc (Binbin Zhang) 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | 17 | #ifndef KALDI_BASE_KALDI_ERROR_H_ 18 | #define KALDI_BASE_KALDI_ERROR_H_ 1 19 | 20 | #include "utils/log.h" 21 | 22 | namespace kaldi { 23 | 24 | #define KALDI_WARN \ 25 | google::LogMessage(__FILE__, __LINE__, google::GLOG_WARNING).stream() 26 | #define KALDI_ERR \ 27 | google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR).stream() 28 | #define KALDI_LOG \ 29 | google::LogMessage(__FILE__, __LINE__, google::GLOG_INFO).stream() 30 | #define KALDI_VLOG(v) VLOG(v) 31 | 32 | #define KALDI_ASSERT(condition) CHECK(condition) 33 | 34 | 35 | /***** PROGRAM NAME AND VERBOSITY LEVEL *****/ 36 | 37 | /// Called by ParseOptions to set base name (no directory) of the executing 38 | /// program. The name is printed in logging code along with every message, 39 | /// because in our scripts, we often mix together the stderr of many programs. 40 | /// This function is very thread-unsafe. 41 | void SetProgramName(const char *basename); 42 | 43 | /// This is set by util/parse-options.{h,cc} if you set --verbose=? option. 44 | /// Do not use directly, prefer {Get,Set}VerboseLevel(). 45 | extern int32 g_kaldi_verbose_level; 46 | 47 | /// Get verbosity level, usually set via command line '--verbose=' switch. 48 | inline int32 GetVerboseLevel() { return g_kaldi_verbose_level; } 49 | 50 | /// This should be rarely used, except by programs using Kaldi as library; 51 | /// command-line programs set the verbose level automatically from ParseOptions. 52 | inline void SetVerboseLevel(int32 i) { g_kaldi_verbose_level = i; } 53 | 54 | } // namespace kaldi 55 | 56 | #endif // KALDI_BASE_KALDI_ERROR_H_ 57 | 58 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/base/kaldi-types.h: -------------------------------------------------------------------------------- 1 | // base/kaldi-types.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation; Saarland University; 4 | // Jan Silovsky; Yanmin Qian 5 | 6 | // See ../../COPYING for clarification regarding multiple authors 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 16 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 17 | // MERCHANTABLITY OR NON-INFRINGEMENT. 18 | // See the Apache 2 License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #ifndef KALDI_BASE_KALDI_TYPES_H_ 22 | #define KALDI_BASE_KALDI_TYPES_H_ 1 23 | 24 | namespace kaldi { 25 | // TYPEDEFS .................................................................. 26 | #if (KALDI_DOUBLEPRECISION != 0) 27 | typedef double BaseFloat; 28 | #else 29 | typedef float BaseFloat; 30 | #endif 31 | } 32 | 33 | #ifdef _MSC_VER 34 | #include 35 | #define ssize_t SSIZE_T 36 | #endif 37 | 38 | // we can do this a different way if some platform 39 | // we find in the future lacks stdint.h 40 | #include 41 | 42 | // for discussion on what to do if you need compile kaldi 43 | // without OpenFST, see the bottom of this this file 44 | #include 45 | 46 | namespace kaldi { 47 | using ::int16; 48 | using ::int32; 49 | using ::int64; 50 | using ::uint16; 51 | using ::uint32; 52 | using ::uint64; 53 | typedef float float32; 54 | typedef double double64; 55 | } // end namespace kaldi 56 | 57 | // In a theoretical case you decide compile Kaldi without the OpenFST 58 | // comment the previous namespace statement and uncomment the following 59 | /* 60 | namespace kaldi { 61 | typedef int8_t int8; 62 | typedef int16_t int16; 63 | typedef int32_t int32; 64 | typedef int64_t int64; 65 | 66 | typedef uint8_t uint8; 67 | typedef uint16_t uint16; 68 | typedef uint32_t uint32; 69 | typedef uint64_t uint64; 70 | typedef float float32; 71 | typedef double double64; 72 | } // end namespace kaldi 73 | */ 74 | 75 | #endif // KALDI_BASE_KALDI_TYPES_H_ 76 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/fstbin/fstaddselfloops.cc: -------------------------------------------------------------------------------- 1 | // fstbin/fstaddselfloops.cc 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #include "base/kaldi-common.h" 21 | #include "fst/fstlib.h" 22 | #include "fstext/determinize-star.h" 23 | #include "fstext/fstext-utils.h" 24 | #include "fstext/kaldi-fst-io.h" 25 | #include "util/parse-options.h" 26 | #include "util/simple-io-funcs.h" 27 | 28 | /* some test examples: 29 | pushd ~/tmpdir 30 | ( echo 3; echo 4) > in.list 31 | ( echo 5; echo 6) > out.list 32 | ( echo "0 0 0 0"; echo "0 0" ) | fstcompile | fstaddselfloops in.list out.list 33 | | fstprint ( echo "0 1 0 1"; echo " 0 2 1 0"; echo "1 0"; echo "2 0"; ) | 34 | fstcompile | fstaddselfloops in.list out.list | fstprint 35 | */ 36 | 37 | int main(int argc, char *argv[]) { 38 | try { 39 | using namespace kaldi; // NOLINT 40 | using namespace fst; // NOLINT 41 | using kaldi::int32; 42 | 43 | const char *usage = 44 | "Adds self-loops to states of an FST to propagate disambiguation " 45 | "symbols through it\n" 46 | "They are added on each final state and each state with non-epsilon " 47 | "output symbols\n" 48 | "on at least one arc out of the state. Useful in conjunction with " 49 | "predeterminize\n" 50 | "\n" 51 | "Usage: fstaddselfloops in-disambig-list out-disambig-list [in.fst " 52 | "[out.fst] ]\n" 53 | "E.g: fstaddselfloops in.list out.list < in.fst > withloops.fst\n" 54 | "in.list and out.list are lists of integers, one per line, of the\n" 55 | "same length.\n"; 56 | 57 | ParseOptions po(usage); 58 | po.Read(argc, argv); 59 | 60 | if (po.NumArgs() < 2 || po.NumArgs() > 4) { 61 | po.PrintUsage(); 62 | exit(1); 63 | } 64 | 65 | std::string disambig_in_rxfilename = po.GetArg(1), 66 | disambig_out_rxfilename = po.GetArg(2), 67 | fst_in_filename = po.GetOptArg(3), 68 | fst_out_filename = po.GetOptArg(4); 69 | 70 | VectorFst *fst = ReadFstKaldi(fst_in_filename); 71 | 72 | std::vector disambig_in; 73 | if (!ReadIntegerVectorSimple(disambig_in_rxfilename, &disambig_in)) 74 | KALDI_ERR 75 | << "fstaddselfloops: Could not read disambiguation symbols from " 76 | << kaldi::PrintableRxfilename(disambig_in_rxfilename); 77 | 78 | std::vector disambig_out; 79 | if (!ReadIntegerVectorSimple(disambig_out_rxfilename, &disambig_out)) 80 | KALDI_ERR 81 | << "fstaddselfloops: Could not read disambiguation symbols from " 82 | << kaldi::PrintableRxfilename(disambig_out_rxfilename); 83 | 84 | if (disambig_in.size() != disambig_out.size()) 85 | KALDI_ERR 86 | << "fstaddselfloops: mismatch in size of disambiguation symbols"; 87 | 88 | AddSelfLoops(fst, disambig_in, disambig_out); 89 | 90 | WriteFstKaldi(*fst, fst_out_filename); 91 | 92 | delete fst; 93 | 94 | return 0; 95 | } catch (const std::exception &e) { 96 | std::cerr << e.what(); 97 | return -1; 98 | } 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/fstbin/fstisstochastic.cc: -------------------------------------------------------------------------------- 1 | // fstbin/fstisstochastic.cc 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #include "base/kaldi-common.h" 21 | #include "fst/fstlib.h" 22 | #include "fstext/fstext-utils.h" 23 | #include "fstext/kaldi-fst-io.h" 24 | #include "util/kaldi-io.h" 25 | #include "util/parse-options.h" 26 | 27 | // e.g. of test: 28 | // echo " 0 0" | fstcompile | fstisstochastic 29 | // should return 0 and print "0 0" [meaning, min and 30 | // max weight are one = exp(0)] 31 | // echo " 0 1" | fstcompile | fstisstochastic 32 | // should return 1, not stochastic, and print 1 1 33 | // (echo "0 0 0 0 0.693147 "; echo "0 1 0 0 0.693147 "; echo "1 0" ) | 34 | // fstcompile | fstisstochastic should return 0, stochastic; it prints "0 35 | // -1.78e-07" for me (echo "0 0 0 0 0.693147 "; echo "0 1 0 0 0.693147 "; echo 36 | // "1 0" ) | fstcompile | fstisstochastic --test-in-log=false should return 1, 37 | // not stochastic in tropical; it prints "0 0.693147" for me (echo "0 0 0 0 0 "; 38 | // echo "0 1 0 0 0 "; echo "1 0" ) | fstcompile | fstisstochastic 39 | // --test-in-log=false should return 0, stochastic in tropical; it prints "0 0" 40 | // for me (echo "0 0 0 0 0.693147 "; echo "0 1 0 0 0.693147 "; echo "1 0" ) | 41 | // fstcompile | fstisstochastic --test-in-log=false --delta=1 returns 0 even 42 | // though not stochastic because we gave it an absurdly large delta. 43 | 44 | int main(int argc, char *argv[]) { 45 | try { 46 | using namespace kaldi; // NOLINT 47 | using namespace fst; // NOLINT 48 | using kaldi::int32; 49 | 50 | const char *usage = 51 | "Checks whether an FST is stochastic and exits with success if so.\n" 52 | "Prints out maximum error (in log units).\n" 53 | "\n" 54 | "Usage: fstisstochastic [ in.fst ]\n"; 55 | 56 | float delta = 0.01; 57 | bool test_in_log = true; 58 | 59 | ParseOptions po(usage); 60 | po.Register("delta", &delta, "Maximum error to accept."); 61 | po.Register("test-in-log", &test_in_log, 62 | "Test stochasticity in log semiring."); 63 | po.Read(argc, argv); 64 | 65 | if (po.NumArgs() > 1) { 66 | po.PrintUsage(); 67 | exit(1); 68 | } 69 | 70 | std::string fst_in_filename = po.GetOptArg(1); 71 | 72 | Fst *fst = ReadFstKaldiGeneric(fst_in_filename); 73 | 74 | bool ans; 75 | StdArc::Weight min, max; 76 | if (test_in_log) 77 | ans = IsStochasticFstInLog(*fst, delta, &min, &max); 78 | else 79 | ans = IsStochasticFst(*fst, delta, &min, &max); 80 | 81 | std::cout << min.Value() << " " << max.Value() << '\n'; 82 | delete fst; 83 | if (ans) 84 | return 0; // success; 85 | else 86 | return 1; 87 | } catch (const std::exception &e) { 88 | std::cerr << e.what(); 89 | return -1; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/fstbin/fstminimizeencoded.cc: -------------------------------------------------------------------------------- 1 | // fstbin/fstminimizeencoded.cc 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #include "base/kaldi-common.h" 21 | #include "fst/fstlib.h" 22 | #include "fstext/determinize-star.h" 23 | #include "fstext/fstext-utils.h" 24 | #include "fstext/kaldi-fst-io.h" 25 | #include "util/kaldi-io.h" 26 | #include "util/parse-options.h" 27 | #include "util/text-utils.h" 28 | 29 | /* some test examples: 30 | ( echo "0 0 0 0"; echo "0 0" ) | fstcompile | fstminimizeencoded | fstprint 31 | ( echo "0 1 0 0"; echo " 0 2 0 0"; echo "1 0"; echo "2 0"; ) | fstcompile | 32 | fstminimizeencoded | fstprint 33 | */ 34 | 35 | int main(int argc, char *argv[]) { 36 | try { 37 | using namespace kaldi; // NOLINT 38 | using namespace fst; // NOLINT 39 | using kaldi::int32; 40 | 41 | const char *usage = 42 | "Minimizes FST after encoding [similar to fstminimize, but no " 43 | "weight-pushing]\n" 44 | "\n" 45 | "Usage: fstminimizeencoded [in.fst [out.fst] ]\n"; 46 | 47 | float delta = kDelta; 48 | ParseOptions po(usage); 49 | po.Register("delta", &delta, 50 | "Delta likelihood used for quantization of weights"); 51 | po.Read(argc, argv); 52 | 53 | if (po.NumArgs() > 2) { 54 | po.PrintUsage(); 55 | exit(1); 56 | } 57 | 58 | std::string fst_in_filename = po.GetOptArg(1), 59 | fst_out_filename = po.GetOptArg(2); 60 | 61 | VectorFst *fst = ReadFstKaldi(fst_in_filename); 62 | 63 | MinimizeEncoded(fst, delta); 64 | 65 | WriteFstKaldi(*fst, fst_out_filename); 66 | 67 | delete fst; 68 | return 0; 69 | } catch (const std::exception &e) { 70 | std::cerr << e.what(); 71 | return -1; 72 | } 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/fstext/fstext-lib.h: -------------------------------------------------------------------------------- 1 | // fstext/fstext-lib.h 2 | 3 | // Copyright 2009-2012 Microsoft Corporation Johns Hopkins University (author: 4 | // Daniel Povey) 5 | 6 | // See ../../COPYING for clarification regarding multiple authors 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 16 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 17 | // MERCHANTABLITY OR NON-INFRINGEMENT. 18 | // See the Apache 2 License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #ifndef KALDI_FSTEXT_FSTEXT_LIB_H_ 22 | #define KALDI_FSTEXT_FSTEXT_LIB_H_ 23 | 24 | #include "fst/fstlib.h" 25 | #include "fstext/determinize-lattice.h" 26 | #include "fstext/determinize-star.h" 27 | #include "fstext/fstext-utils.h" 28 | #include "fstext/kaldi-fst-io.h" 29 | #include "fstext/lattice-utils.h" 30 | #include "fstext/lattice-weight.h" 31 | #include "fstext/pre-determinize.h" 32 | #include "fstext/table-matcher.h" 33 | 34 | #endif // KALDI_FSTEXT_FSTEXT_LIB_H_ 35 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/fstext/remove-eps-local.h: -------------------------------------------------------------------------------- 1 | // fstext/remove-eps-local.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | // 2014 Johns Hopkins University (author: Daniel Povey) 5 | 6 | // See ../../COPYING for clarification regarding multiple authors 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 16 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 17 | // MERCHANTABLITY OR NON-INFRINGEMENT. 18 | // See the Apache 2 License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #ifndef KALDI_FSTEXT_REMOVE_EPS_LOCAL_H_ 22 | #define KALDI_FSTEXT_REMOVE_EPS_LOCAL_H_ 23 | 24 | #include 25 | #include 26 | 27 | namespace fst { 28 | 29 | /// RemoveEpsLocal remove some (but not necessarily all) epsilons in an FST, 30 | /// using an algorithm that is guaranteed to never increase the number of arcs 31 | /// in the FST (and will also never increase the number of states). The 32 | /// algorithm is not optimal but is reasonably clever. It does not just remove 33 | /// epsilon arcs;it also combines pairs of input-epsilon and output-epsilon arcs 34 | /// into one. 35 | /// The algorithm preserves equivalence and stochasticity in the given semiring. 36 | /// If you want to preserve stochasticity in a different semiring (e.g. log), 37 | /// then use RemoveEpsLocalSpecial, which only works for StdArc but which 38 | /// preserves stochasticity, where possible (*) in the LogArc sense. The reason 39 | /// that we can't just cast to a different semiring is that in that case we 40 | /// would no longer be able to guarantee equivalence in the original semiring 41 | /// (this arises from what happens when we combine identical arcs). 42 | /// (*) by "where possible".. there are situations where we wouldn't be able to 43 | /// preserve stochasticity in the LogArc sense while maintaining equivalence in 44 | /// the StdArc sense, so in these situations we maintain equivalence. 45 | 46 | template 47 | void RemoveEpsLocal(MutableFst *fst); 48 | 49 | /// As RemoveEpsLocal but takes care to preserve stochasticity 50 | /// when cast to LogArc. 51 | inline void RemoveEpsLocalSpecial(MutableFst *fst); 52 | 53 | } // namespace fst 54 | 55 | #include "fstext/remove-eps-local-inl.h" 56 | 57 | #endif // KALDI_FSTEXT_REMOVE_EPS_LOCAL_H_ 58 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/itf/options-itf.h: -------------------------------------------------------------------------------- 1 | // itf/options-itf.h 2 | 3 | // Copyright 2013 Tanel Alumae, Tallinn University of Technology 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #ifndef KALDI_ITF_OPTIONS_ITF_H_ 21 | #define KALDI_ITF_OPTIONS_ITF_H_ 1 22 | 23 | #include 24 | 25 | #include "base/kaldi-common.h" 26 | 27 | namespace kaldi { 28 | 29 | class OptionsItf { 30 | public: 31 | virtual void Register(const std::string &name, 32 | bool *ptr, const std::string &doc) = 0; 33 | virtual void Register(const std::string &name, 34 | int32 *ptr, const std::string &doc) = 0; 35 | virtual void Register(const std::string &name, 36 | uint32 *ptr, const std::string &doc) = 0; 37 | virtual void Register(const std::string &name, 38 | float *ptr, const std::string &doc) = 0; 39 | virtual void Register(const std::string &name, 40 | double *ptr, const std::string &doc) = 0; 41 | virtual void Register(const std::string &name, 42 | std::string *ptr, const std::string &doc) = 0; 43 | 44 | virtual ~OptionsItf() {} 45 | }; 46 | 47 | } // namespace kaldi 48 | 49 | #endif // KALDI_ITF_OPTIONS_ITF_H_ 50 | 51 | 52 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/lat/CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | # So many lint errors now, we just ignore it now. 2 | # We will try to fix it in the future. 3 | exclude_files=.* 4 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/lm/arpa-lm-compiler.h: -------------------------------------------------------------------------------- 1 | // lm/arpa-lm-compiler.h 2 | 3 | // Copyright 2009-2011 Gilles Boulianne 4 | // Copyright 2016 Smart Action LLC (kkm) 5 | 6 | // See ../../COPYING for clarification regarding multiple authors 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 16 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 17 | // MERCHANTABLITY OR NON-INFRINGEMENT. 18 | // See the Apache 2 License for the specific language governing permissions and 19 | // limitations under the License. 20 | 21 | #ifndef KALDI_LM_ARPA_LM_COMPILER_H_ 22 | #define KALDI_LM_ARPA_LM_COMPILER_H_ 23 | 24 | #include 25 | 26 | #include "lm/arpa-file-parser.h" 27 | 28 | namespace kaldi { 29 | 30 | class ArpaLmCompilerImplInterface; 31 | 32 | class ArpaLmCompiler : public ArpaFileParser { 33 | public: 34 | ArpaLmCompiler(const ArpaParseOptions& options, int sub_eps, 35 | fst::SymbolTable* symbols) 36 | : ArpaFileParser(options, symbols), sub_eps_(sub_eps), impl_(NULL) {} 37 | ~ArpaLmCompiler(); 38 | 39 | const fst::StdVectorFst& Fst() const { return fst_; } 40 | fst::StdVectorFst* MutableFst() { return &fst_; } 41 | 42 | protected: 43 | // ArpaFileParser overrides. 44 | virtual void HeaderAvailable(); 45 | virtual void ConsumeNGram(const NGram& ngram); 46 | virtual void ReadComplete(); 47 | 48 | private: 49 | // this function removes states that only have a backoff arc coming 50 | // out of them. 51 | void RemoveRedundantStates(); 52 | void Check() const; 53 | 54 | int sub_eps_; 55 | ArpaLmCompilerImplInterface* impl_; // Owned. 56 | fst::StdVectorFst fst_; 57 | template 58 | friend class ArpaLmCompilerImpl; 59 | }; 60 | 61 | } // namespace kaldi 62 | 63 | #endif // KALDI_LM_ARPA_LM_COMPILER_H_ 64 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/util/const-integer-set-inl.h: -------------------------------------------------------------------------------- 1 | // util/const-integer-set-inl.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #ifndef KALDI_UTIL_CONST_INTEGER_SET_INL_H_ 21 | #define KALDI_UTIL_CONST_INTEGER_SET_INL_H_ 22 | 23 | // Do not include this file directly. It is included by const-integer-set.h 24 | 25 | namespace kaldi { 26 | 27 | template 28 | void ConstIntegerSet::InitInternal() { 29 | KALDI_ASSERT_IS_INTEGER_TYPE(I); 30 | quick_set_.clear(); // just in case we previously had data. 31 | if (slow_set_.size() == 0) { 32 | lowest_member_ = (I)1; 33 | highest_member_ = (I)0; 34 | contiguous_ = false; 35 | quick_ = false; 36 | } else { 37 | lowest_member_ = slow_set_.front(); 38 | highest_member_ = slow_set_.back(); 39 | size_t range = highest_member_ + 1 - lowest_member_; 40 | if (range == slow_set_.size()) { 41 | contiguous_ = true; 42 | quick_ = false; 43 | } else { 44 | contiguous_ = false; 45 | // If it would be more compact to store as bool 46 | if (range < slow_set_.size() * 8 * sizeof(I)) { 47 | // (assuming 1 bit per element)... 48 | quick_set_.resize(range, false); 49 | for (size_t i = 0; i < slow_set_.size(); i++) 50 | quick_set_[slow_set_[i] - lowest_member_] = true; 51 | quick_ = true; 52 | } else { 53 | quick_ = false; 54 | } 55 | } 56 | } 57 | } 58 | 59 | template 60 | int ConstIntegerSet::count(I i) const { 61 | if (i < lowest_member_ || i > highest_member_) { 62 | return 0; 63 | } else { 64 | if (contiguous_) return true; 65 | if (quick_) { 66 | return (quick_set_[i - lowest_member_] ? 1 : 0); 67 | } else { 68 | bool ans = std::binary_search(slow_set_.begin(), slow_set_.end(), i); 69 | return (ans ? 1 : 0); 70 | } 71 | } 72 | } 73 | 74 | template 75 | void ConstIntegerSet::Write(std::ostream &os, bool binary) const { 76 | WriteIntegerVector(os, binary, slow_set_); 77 | } 78 | 79 | template 80 | void ConstIntegerSet::Read(std::istream &is, bool binary) { 81 | ReadIntegerVector(is, binary, &slow_set_); 82 | InitInternal(); 83 | } 84 | 85 | } // end namespace kaldi 86 | 87 | #endif // KALDI_UTIL_CONST_INTEGER_SET_INL_H_ 88 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/util/const-integer-set.h: -------------------------------------------------------------------------------- 1 | // util/const-integer-set.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | #ifndef KALDI_UTIL_CONST_INTEGER_SET_H_ 21 | #define KALDI_UTIL_CONST_INTEGER_SET_H_ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "util/stl-utils.h" 28 | 29 | /* ConstIntegerSet is a way to efficiently test whether something is in a 30 | supplied set of integers. It can be initialized from a vector or set, but 31 | never changed after that. It either uses a sorted vector or an array of 32 | bool, depending on the input. It behaves like a const version of an STL set, 33 | with only a subset of the functionality, except all the member functions are 34 | upper-case. 35 | 36 | Note that we could get rid of the member slow_set_, but we'd have to 37 | do more work to implement an iterator type. This would save memory. 38 | */ 39 | 40 | namespace kaldi { 41 | 42 | template 43 | class ConstIntegerSet { 44 | public: 45 | ConstIntegerSet() : lowest_member_(1), highest_member_(0) {} 46 | 47 | void Init(const std::vector &input) { 48 | slow_set_ = input; 49 | SortAndUniq(&slow_set_); 50 | InitInternal(); 51 | } 52 | 53 | void Init(const std::set &input) { 54 | CopySetToVector(input, &slow_set_); 55 | InitInternal(); 56 | } 57 | 58 | explicit ConstIntegerSet(const std::vector &input) : slow_set_(input) { 59 | SortAndUniq(&slow_set_); 60 | InitInternal(); 61 | } 62 | explicit ConstIntegerSet(const std::set &input) { 63 | CopySetToVector(input, &slow_set_); 64 | InitInternal(); 65 | } 66 | explicit ConstIntegerSet(const ConstIntegerSet &other) 67 | : slow_set_(other.slow_set_) { 68 | InitInternal(); 69 | } 70 | 71 | int count(I i) const; // returns 1 or 0. 72 | 73 | typedef typename std::vector::const_iterator iterator; 74 | iterator begin() const { return slow_set_.begin(); } 75 | iterator end() const { return slow_set_.end(); } 76 | size_t size() const { return slow_set_.size(); } 77 | bool empty() const { return slow_set_.empty(); } 78 | 79 | void Write(std::ostream &os, bool binary) const; 80 | void Read(std::istream &is, bool binary); 81 | 82 | private: 83 | I lowest_member_; 84 | I highest_member_; 85 | bool contiguous_; 86 | bool quick_; 87 | std::vector quick_set_; 88 | std::vector slow_set_; 89 | void InitInternal(); 90 | }; 91 | 92 | } // end namespace kaldi 93 | 94 | #include "util/const-integer-set-inl.h" 95 | 96 | #endif // KALDI_UTIL_CONST_INTEGER_SET_H_ 97 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/util/kaldi-io-inl.h: -------------------------------------------------------------------------------- 1 | // util/kaldi-io-inl.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | #ifndef KALDI_UTIL_KALDI_IO_INL_H_ 20 | #define KALDI_UTIL_KALDI_IO_INL_H_ 21 | 22 | #include 23 | 24 | namespace kaldi { 25 | 26 | bool Input::Open(const std::string &rxfilename, bool *binary) { 27 | return OpenInternal(rxfilename, true, binary); 28 | } 29 | 30 | bool Input::OpenTextMode(const std::string &rxfilename) { 31 | return OpenInternal(rxfilename, false, NULL); 32 | } 33 | 34 | bool Input::IsOpen() { return impl_ != NULL; } 35 | 36 | bool Output::IsOpen() { return impl_ != NULL; } 37 | 38 | } // end namespace kaldi. 39 | 40 | #endif // KALDI_UTIL_KALDI_IO_INL_H_ 41 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/util/kaldi-pipebuf.h: -------------------------------------------------------------------------------- 1 | // util/kaldi-pipebuf.h 2 | 3 | // Copyright 2009-2011 Ondrej Glembek 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | 20 | /** @file kaldi-pipebuf.h 21 | * This is an Kaldi C++ Library header. 22 | */ 23 | 24 | #ifndef KALDI_UTIL_KALDI_PIPEBUF_H_ 25 | #define KALDI_UTIL_KALDI_PIPEBUF_H_ 26 | 27 | #include 28 | #if !defined(_LIBCPP_VERSION) // libc++ 29 | #include 30 | #else 31 | #include "util/basic-filebuf.h" 32 | #endif 33 | 34 | namespace kaldi { 35 | // This class provides a way to initialize a filebuf with a FILE* pointer 36 | // directly; it will not close the file pointer when it is deleted. 37 | // The C++ standard does not allow implementations of C++ to provide 38 | // this constructor within basic_filebuf, which makes it hard to deal 39 | // with pipes using completely native C++. This is a workaround 40 | 41 | #ifdef _MSC_VER 42 | #elif defined(_LIBCPP_VERSION) // libc++ 43 | template > 44 | class basic_pipebuf : public basic_filebuf { 45 | public: 46 | typedef basic_pipebuf ThisType; 47 | 48 | public: 49 | basic_pipebuf(FILE *fptr, std::ios_base::openmode mode) 50 | : basic_filebuf() { 51 | this->open(fptr, mode); 52 | if (!this->is_open()) { 53 | KALDI_WARN << "Error initializing pipebuf"; // probably indicates 54 | // code error, if the fptr was good. 55 | return; 56 | } 57 | } 58 | }; // class basic_pipebuf 59 | #else 60 | template > 61 | class basic_pipebuf : public std::basic_filebuf { 62 | public: 63 | typedef basic_pipebuf ThisType; 64 | 65 | public: 66 | basic_pipebuf(FILE *fptr, std::ios_base::openmode mode) 67 | : std::basic_filebuf() { 68 | this->_M_file.sys_open(fptr, mode); 69 | if (!this->is_open()) { 70 | KALDI_WARN << "Error initializing pipebuf"; // probably indicates 71 | // code error, if the fptr was good. 72 | return; 73 | } 74 | this->_M_mode = mode; 75 | this->_M_buf_size = BUFSIZ; 76 | this->_M_allocate_internal_buffer(); 77 | this->_M_reading = false; 78 | this->_M_writing = false; 79 | this->_M_set_buffer(-1); 80 | } 81 | }; // class basic_pipebuf 82 | #endif // _MSC_VER 83 | 84 | } // namespace kaldi 85 | 86 | #endif // KALDI_UTIL_KALDI_PIPEBUF_H_ 87 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/util/simple-io-funcs.cc: -------------------------------------------------------------------------------- 1 | // util/simple-io-funcs.cc 2 | 3 | // Copyright 2009-2011 Microsoft Corporation 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | #include "util/simple-io-funcs.h" 20 | #include "util/text-utils.h" 21 | 22 | namespace kaldi { 23 | 24 | bool WriteIntegerVectorSimple(const std::string &wxfilename, 25 | const std::vector &list) { 26 | kaldi::Output ko; 27 | // false, false is: text-mode, no Kaldi header. 28 | if (!ko.Open(wxfilename, false, false)) return false; 29 | for (size_t i = 0; i < list.size(); i++) ko.Stream() << list[i] << '\n'; 30 | return ko.Close(); 31 | } 32 | 33 | bool ReadIntegerVectorSimple(const std::string &rxfilename, 34 | std::vector *list) { 35 | kaldi::Input ki; 36 | if (!ki.OpenTextMode(rxfilename)) return false; 37 | std::istream &is = ki.Stream(); 38 | int32 i; 39 | list->clear(); 40 | while (!(is >> i).fail()) list->push_back(i); 41 | is >> std::ws; 42 | return is.eof(); // should be eof, or junk at end of file. 43 | } 44 | 45 | bool WriteIntegerVectorVectorSimple( 46 | const std::string &wxfilename, 47 | const std::vector > &list) { 48 | kaldi::Output ko; 49 | // false, false is: text-mode, no Kaldi header. 50 | if (!ko.Open(wxfilename, false, false)) return false; 51 | std::ostream &os = ko.Stream(); 52 | for (size_t i = 0; i < list.size(); i++) { 53 | for (size_t j = 0; j < list[i].size(); j++) { 54 | os << list[i][j]; 55 | if (j + 1 < list[i].size()) os << ' '; 56 | } 57 | os << '\n'; 58 | } 59 | return ko.Close(); 60 | } 61 | 62 | bool ReadIntegerVectorVectorSimple(const std::string &rxfilename, 63 | std::vector > *list) { 64 | kaldi::Input ki; 65 | if (!ki.OpenTextMode(rxfilename)) return false; 66 | std::istream &is = ki.Stream(); 67 | list->clear(); 68 | std::string line; 69 | while (std::getline(is, line)) { 70 | std::vector v; 71 | if (!SplitStringToIntegers(line, " \t\r", true, &v)) { 72 | list->clear(); 73 | return false; 74 | } 75 | list->push_back(v); 76 | } 77 | return is.eof(); // if we're not at EOF, something weird happened. 78 | } 79 | 80 | } // end namespace kaldi 81 | -------------------------------------------------------------------------------- /android/src/main/cpp/kaldi/util/simple-io-funcs.h: -------------------------------------------------------------------------------- 1 | // util/simple-io-funcs.h 2 | 3 | // Copyright 2009-2011 Microsoft Corporation; Jan Silovsky 4 | 5 | // See ../../COPYING for clarification regarding multiple authors 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 15 | // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 16 | // MERCHANTABLITY OR NON-INFRINGEMENT. 17 | // See the Apache 2 License for the specific language governing permissions and 18 | // limitations under the License. 19 | #ifndef KALDI_UTIL_SIMPLE_IO_FUNCS_H_ 20 | #define KALDI_UTIL_SIMPLE_IO_FUNCS_H_ 21 | 22 | #include 23 | #include 24 | #include "util/kaldi-io.h" 25 | 26 | // This header contains some utilities for reading some common, simple text 27 | // formats:integers in files, one per line, and integers in files, possibly 28 | // multiple per line. these are not really fully native Kaldi formats; they are 29 | // mostly for small files that might be generated by scripts, and can be read 30 | // all at one time. for longer files of this type, we would probably use the 31 | // Table code. 32 | 33 | namespace kaldi { 34 | 35 | /// WriteToList attempts to write this list of integers, one per line, 36 | /// to the given file, in text format. 37 | /// returns true if succeeded. 38 | bool WriteIntegerVectorSimple(const std::string &wxfilename, 39 | const std::vector &v); 40 | 41 | /// ReadFromList attempts to read this list of integers, one per line, 42 | /// from the given file, in text format. 43 | /// returns true if succeeded. 44 | bool ReadIntegerVectorSimple(const std::string &rxfilename, 45 | std::vector *v); 46 | 47 | // This is a file format like: 48 | // 1 2 49 | // 3 50 | // 51 | // 4 5 6 52 | // etc. 53 | bool WriteIntegerVectorVectorSimple(const std::string &wxfilename, 54 | const std::vector > &v); 55 | 56 | bool ReadIntegerVectorVectorSimple(const std::string &rxfilename, 57 | std::vector > *v); 58 | 59 | } // end namespace kaldi. 60 | 61 | #endif // KALDI_UTIL_SIMPLE_IO_FUNCS_H_ 62 | -------------------------------------------------------------------------------- /android/src/main/cpp/patch/CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | exclude_files=.* 2 | -------------------------------------------------------------------------------- /android/src/main/cpp/patch/openfst/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | #-DHAVE_CONFIG_H -I./../include -fno-exceptions -funsigned-char -std=c++11 -MT symbol-table.lo -MD -MP -MF .deps/symbol-table.Tpo -c symbol-table.cc -fno-common -DPIC -o .libs/symbol-table.o 3 | 4 | include_directories(./include/) 5 | install(DIRECTORY include/ DESTINATION include/ 6 | FILES_MATCHING PATTERN "*.h") 7 | 8 | add_subdirectory(lib) 9 | add_subdirectory(script) 10 | 11 | if(HAVE_BIN) 12 | add_subdirectory(bin) 13 | endif(HAVE_BIN) 14 | 15 | add_subdirectory(extensions) 16 | 17 | if(BUILD_TESTING) 18 | enable_testing() 19 | add_subdirectory(test) 20 | endif(BUILD_TESTING) -------------------------------------------------------------------------------- /android/src/main/cpp/patch/openfst/src/extensions/special/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB HEADER_FILES ../../include/fst/extensions/special/*.h) 2 | message(STATUS "${HEADER_FILES}") 3 | 4 | if(HAVE_BIN) 5 | add_executable(fstspecial-bin 6 | ../../bin/fstconvert.cc 7 | ../../bin/fstconvert-main.cc 8 | phi-fst.cc 9 | rho-fst.cc 10 | sigma-fst.cc 11 | ) 12 | 13 | set_target_properties(fstspecial-bin PROPERTIE 14 | FOLDER special/bin 15 | OUTPUT_NAME fstspecial 16 | ) 17 | 18 | target_link_libraries(fstspecial-bin 19 | fstscript 20 | fst 21 | ${CMAKE_DL_LIBS} 22 | ) 23 | endif(HAVE_BIN) 24 | 25 | 26 | add_library(fstspecial 27 | phi-fst.cc 28 | rho-fst.cc 29 | sigma-fst.cc 30 | ${HEADER_FILES} 31 | ) 32 | 33 | set_target_properties(fstspecial PROPERTIES 34 | SOVERSION "${SOVERSION}" 35 | FOLDER special 36 | ) 37 | target_link_libraries(fstspecial 38 | fst 39 | ) 40 | 41 | set(FST_SPECIAL_INSTALL_TARGETS fstspecial) 42 | if(HAVE_BIN) 43 | list(APPEND FST_SPECIAL_INSTALL_TARGETS fstspecial-bin) 44 | endif() 45 | 46 | install(TARGETS ${FST_SPECIAL_INSTALL_TARGETS} 47 | LIBRARY DESTINATION lib 48 | RUNTIME DESTINATION bin 49 | ARCHIVE DESTINATION lib 50 | ) 51 | 52 | function (add_module _name) 53 | add_library(${ARGV}) 54 | if (TARGET ${_name}) 55 | target_link_libraries(${_name} fst) 56 | set_target_properties(${_name} 57 | PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS true 58 | FOLDER special/modules 59 | ) 60 | endif() 61 | 62 | install(TARGETS ${_name} LIBRARY DESTINATION lib/fst) 63 | endfunction() 64 | 65 | add_module(phi-fst MODULE phi-fst.cc) 66 | add_module(rho-fst MODULE rho-fst.cc) 67 | add_module(sigma-fst MODULE sigma-fst.cc) 68 | -------------------------------------------------------------------------------- /android/src/main/cpp/patch/openfst/src/include/fst/log.h: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | // 13 | // See www.openfst.org for extensive documentation on this weighted 14 | // finite-state transducer library. 15 | // 16 | // Google-style logging declarations and inline definitions. 17 | 18 | #ifndef FST_LIB_LOG_H_ 19 | #define FST_LIB_LOG_H_ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | using std::string; 29 | 30 | DECLARE_int32(v); 31 | 32 | class LogMessage { 33 | public: 34 | LogMessage(const string &type) : fatal_(type == "FATAL") { 35 | std::cerr << type << ": "; 36 | } 37 | ~LogMessage() { 38 | std::cerr << std::endl; 39 | if(fatal_) 40 | exit(1); 41 | } 42 | std::ostream &stream() { return std::cerr; } 43 | 44 | private: 45 | bool fatal_; 46 | }; 47 | 48 | // #define LOG(type) LogMessage(#type).stream() 49 | // #define VLOG(level) if ((level) <= FLAGS_v) LOG(INFO) 50 | 51 | // Checks 52 | inline void FstCheck(bool x, const char* expr, 53 | const char *file, int line) { 54 | if (!x) { 55 | LOG(FATAL) << "Check failed: \"" << expr 56 | << "\" file: " << file 57 | << " line: " << line; 58 | } 59 | } 60 | 61 | // #define CHECK(x) FstCheck(static_cast(x), #x, __FILE__, __LINE__) 62 | // #define CHECK_EQ(x, y) CHECK((x) == (y)) 63 | // #define CHECK_LT(x, y) CHECK((x) < (y)) 64 | // #define CHECK_GT(x, y) CHECK((x) > (y)) 65 | // #define CHECK_LE(x, y) CHECK((x) <= (y)) 66 | // #define CHECK_GE(x, y) CHECK((x) >= (y)) 67 | // #define CHECK_NE(x, y) CHECK((x) != (y)) 68 | 69 | // Debug checks 70 | // #define DCHECK(x) assert(x) 71 | // #define DCHECK_EQ(x, y) DCHECK((x) == (y)) 72 | // #define DCHECK_LT(x, y) DCHECK((x) < (y)) 73 | // #define DCHECK_GT(x, y) DCHECK((x) > (y)) 74 | // #define DCHECK_LE(x, y) DCHECK((x) <= (y)) 75 | // #define DCHECK_GE(x, y) DCHECK((x) >= (y)) 76 | // #define DCHECK_NE(x, y) DCHECK((x) != (y)) 77 | 78 | 79 | // Ports 80 | #define ATTRIBUTE_DEPRECATED __attribute__((deprecated)) 81 | 82 | #endif // FST_LIB_LOG_H_ 83 | -------------------------------------------------------------------------------- /android/src/main/cpp/post_processor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(post_processor STATIC 2 | post_processor.cc 3 | ) 4 | target_link_libraries(post_processor PUBLIC utils) -------------------------------------------------------------------------------- /android/src/main/cpp/post_processor/post_processor.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Xingchen Song sxc19@mails.tsinghua.edu.cn 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License 14 | 15 | #include "post_processor/post_processor.h" 16 | 17 | #include 18 | #include 19 | 20 | #include "utils/string.h" 21 | 22 | namespace wenet { 23 | 24 | std::string PostProcessor::ProcessSpace(const std::string& str) { 25 | std::string result = str; 26 | // 1. remove ' ' if needed 27 | // only spaces between mandarin words need to be removed, please note that 28 | // if str contains '_', we assume that the decoding type must be 29 | // `CtcPrefixBeamSearch` and this branch will do nothing since str must be 30 | // obtained via "".join() (in function `AsrDecoder::UpdateResult()`) 31 | if (opts_.language_type == kMandarinEnglish && !str.empty()) { 32 | result.clear(); 33 | // split str by ' ' 34 | std::vector words; 35 | std::stringstream ss(str); 36 | std::string tmp; 37 | while (ss >> tmp) { 38 | words.push_back(tmp); 39 | } 40 | // check english word 41 | bool is_englishword_prev = false; 42 | bool is_englishword_now = false; 43 | for (std::string& w : words) { 44 | is_englishword_now = CheckEnglishWord(w); 45 | if (is_englishword_prev && is_englishword_now) { 46 | result += (' ' + w); 47 | } else { 48 | result += (w); 49 | } 50 | is_englishword_prev = is_englishword_now; 51 | } 52 | } 53 | // 2. replace '_' with ' ' 54 | // this should be done for all cases (both kMandarinEnglish and kIndoEuropean) 55 | result = ProcessBlank(result, opts_.lowercase); 56 | return result; 57 | } 58 | 59 | std::string PostProcessor::Process(const std::string& str, bool finish) { 60 | std::string result; 61 | result = ProcessSpace(str); 62 | // TODO(xcsong): do itn/punctuation if finish == true 63 | return result; 64 | } 65 | 66 | } // namespace wenet 67 | -------------------------------------------------------------------------------- /android/src/main/cpp/post_processor/post_processor.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Xingchen Song sxc19@mails.tsinghua.edu.cn 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License 14 | 15 | #ifndef POST_PROCESSOR_POST_PROCESSOR_H_ 16 | #define POST_PROCESSOR_POST_PROCESSOR_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "utils/utils.h" 23 | 24 | namespace wenet { 25 | 26 | enum LanguageType { 27 | // spaces between **mandarin words** should be removed. 28 | // cases of processing spaces with mandarin-only, english-only 29 | // and mandarin-english code-switch can be found in post_processor_test.cc 30 | kMandarinEnglish = 0x00, 31 | // spaces should be kept for most of the 32 | // Indo-European languages (i.e., deutsch or english-deutsch code-switch). 33 | // cases of those languages can be found in post_processor_test.cc 34 | kIndoEuropean = 0x01 35 | }; 36 | 37 | struct PostProcessOptions { 38 | // space options 39 | // The decoded result may contain spaces (' ' or '_'), 40 | // we will process those spaces according to language_type. More details can 41 | // be found in 42 | // https://github.com/wenet-e2e/wenet/issues/583#issuecomment-907994058 43 | LanguageType language_type = kMandarinEnglish; 44 | // whether lowercase letters are required 45 | bool lowercase = true; 46 | }; 47 | 48 | // TODO(xcsong): add itn/punctuation related resource 49 | struct PostProcessResource {}; 50 | 51 | // Post Processor 52 | class PostProcessor { 53 | public: 54 | explicit PostProcessor(PostProcessOptions&& opts) : opts_(std::move(opts)) {} 55 | explicit PostProcessor(const PostProcessOptions& opts) : opts_(opts) {} 56 | // call other functions to do post processing 57 | std::string Process(const std::string& str, bool finish); 58 | // process spaces according to configurations 59 | std::string ProcessSpace(const std::string& str); 60 | // TODO(xcsong): add itn/punctuation 61 | // void InverseTN(const std::string& str); 62 | // void Punctuate(const std::string& str); 63 | 64 | private: 65 | const PostProcessOptions opts_; 66 | 67 | public: 68 | WENET_DISALLOW_COPY_AND_ASSIGN(PostProcessor); 69 | }; 70 | 71 | } // namespace wenet 72 | 73 | #endif // POST_PROCESSOR_POST_PROCESSOR_H_ 74 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(utils STATIC 2 | string.cc 3 | utils.cc 4 | ) 5 | 6 | if(NOT ANDROID) 7 | if(MSVC) 8 | target_link_libraries(utils PUBLIC fst) 9 | else() 10 | target_link_libraries(utils PUBLIC fst dl) 11 | endif() 12 | endif() -------------------------------------------------------------------------------- /android/src/main/cpp/utils/blocking_queue.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_BLOCKING_QUEUE_H_ 16 | #define UTILS_BLOCKING_QUEUE_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "utils/utils.h" 26 | 27 | namespace wenet { 28 | 29 | template 30 | class BlockingQueue { 31 | public: 32 | explicit BlockingQueue(size_t capacity = std::numeric_limits::max()) 33 | : capacity_(capacity) {} 34 | 35 | void Push(const T& value) { 36 | { 37 | std::unique_lock lock(mutex_); 38 | while (queue_.size() >= capacity_) { 39 | not_full_condition_.wait(lock); 40 | } 41 | queue_.push(value); 42 | } 43 | not_empty_condition_.notify_one(); 44 | } 45 | 46 | void Push(T&& value) { 47 | { 48 | std::unique_lock lock(mutex_); 49 | while (queue_.size() >= capacity_) { 50 | not_full_condition_.wait(lock); 51 | } 52 | queue_.push(std::move(value)); 53 | } 54 | not_empty_condition_.notify_one(); 55 | } 56 | 57 | void Push(const std::vector& values) { 58 | { 59 | std::unique_lock lock(mutex_); 60 | for (auto& value : values) { 61 | while (queue_.size() >= capacity_) { 62 | not_empty_condition_.notify_one(); 63 | not_full_condition_.wait(lock); 64 | } 65 | queue_.push(value); 66 | } 67 | } 68 | not_empty_condition_.notify_one(); 69 | } 70 | 71 | void Push(std::vector&& values) { 72 | std::unique_lock lock(mutex_); 73 | for (auto& value : values) { 74 | while (queue_.size() >= capacity_) { 75 | not_empty_condition_.notify_one(); 76 | not_full_condition_.wait(lock); 77 | } 78 | queue_.push(std::move(value)); 79 | } 80 | not_empty_condition_.notify_one(); 81 | } 82 | 83 | T Pop() { 84 | std::unique_lock lock(mutex_); 85 | while (queue_.empty()) { 86 | not_empty_condition_.wait(lock); 87 | } 88 | T t(std::move(queue_.front())); 89 | queue_.pop(); 90 | not_full_condition_.notify_one(); 91 | return t; 92 | } 93 | 94 | // num can be greater than capacity,but it needs to be used with care 95 | std::vector Pop(size_t num) { 96 | std::unique_lock lock(mutex_); 97 | std::vector block_data; 98 | while (block_data.size() < num) { 99 | while (queue_.empty()) { 100 | not_full_condition_.notify_one(); 101 | not_empty_condition_.wait(lock); 102 | } 103 | block_data.push_back(std::move(queue_.front())); 104 | queue_.pop(); 105 | } 106 | not_full_condition_.notify_one(); 107 | return block_data; 108 | } 109 | 110 | bool Empty() const { 111 | std::lock_guard lock(mutex_); 112 | return queue_.empty(); 113 | } 114 | 115 | size_t Size() const { 116 | std::lock_guard lock(mutex_); 117 | return queue_.size(); 118 | } 119 | 120 | void Clear() { 121 | while (!Empty()) { 122 | Pop(); 123 | } 124 | } 125 | 126 | private: 127 | size_t capacity_; 128 | mutable std::mutex mutex_; 129 | std::condition_variable not_full_condition_; 130 | std::condition_variable not_empty_condition_; 131 | std::queue queue_; 132 | 133 | public: 134 | WENET_DISALLOW_COPY_AND_ASSIGN(BlockingQueue); 135 | }; 136 | 137 | } // namespace wenet 138 | 139 | #endif // UTILS_BLOCKING_QUEUE_H_ 140 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/file.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Binbin Zhang (binbzha@qq.com) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_FILE_H_ 16 | #define UTILS_FILE_H_ 17 | 18 | #include 19 | #include 20 | 21 | namespace wenet { 22 | 23 | inline bool FileExists(const std::string& path) { 24 | std::ifstream f(path.c_str()); 25 | return f.good(); 26 | } 27 | 28 | } // namespace wenet 29 | 30 | #endif // UTILS_FILE_H_ 31 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/flags.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_FLAGS_H_ 16 | #define UTILS_FLAGS_H_ 17 | 18 | // Because openfst is a dynamic library compiled with gflags/glog, we must use 19 | // the gflags/glog from openfst to avoid them linked both statically and 20 | // dynamically into the executable. 21 | #include "fst/flags.h" 22 | 23 | #endif // UTILS_FLAGS_H_ 24 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/log.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_LOG_H_ 16 | #define UTILS_LOG_H_ 17 | 18 | // Because openfst is a dynamic library compiled with gflags/glog, we must use 19 | // the gflags/glog from openfst to avoid them linked both statically and 20 | // dynamically into the executable. 21 | #include "fst/log.h" 22 | 23 | #endif // UTILS_LOG_H_ 24 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/string.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_STRING_H_ 16 | #define UTILS_STRING_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "fst/symbol-table.h" 25 | 26 | namespace wenet { 27 | 28 | const char WHITESPACE[] = " \n\r\t\f\v"; 29 | 30 | // Split the string with space or tab. 31 | void SplitString(const std::string& str, std::vector* strs); 32 | 33 | void SplitStringToVector(const std::string& full, const char* delim, 34 | bool omit_empty_strings, 35 | std::vector* out); 36 | 37 | // NOTE(Xingchen Song): we add this function to make it possible to 38 | // support multilingual recipe in the future, in which characters of 39 | // different languages are all encoded in UTF-8 format. 40 | // UTF-8 REF: https://en.wikipedia.org/wiki/UTF-8#Encoding 41 | // Split the UTF-8 string into chars. 42 | void SplitUTF8StringToChars(const std::string& str, 43 | std::vector* chars); 44 | 45 | int UTF8StringLength(const std::string& str); 46 | 47 | // Check whether the UTF-8 char is alphabet or '. 48 | bool CheckEnglishChar(const std::string& ch); 49 | 50 | // Check whether the UTF-8 word is only contains alphabet or '. 51 | bool CheckEnglishWord(const std::string& word); 52 | 53 | std::string JoinString(const std::string& c, 54 | const std::vector& strs); 55 | 56 | // Split the UTF-8 string into words by symbol table. 57 | // Return whether not contains oov. 58 | bool SplitUTF8StringToWords( 59 | const std::string& str, 60 | const std::shared_ptr& symbol_table, 61 | std::vector* words); 62 | 63 | // Replace ▁ with space, then remove head, tail and consecutive space. 64 | std::string ProcessBlank(const std::string& str, bool lowercase); 65 | 66 | std::string Ltrim(const std::string& str); 67 | 68 | std::string Rtrim(const std::string& str); 69 | 70 | std::string Trim(const std::string& str); 71 | 72 | std::string JoinPath(const std::string& left, const std::string& right); 73 | 74 | #ifdef _MSC_VER 75 | std::wstring ToWString(const std::string& str); 76 | #endif 77 | 78 | } // namespace wenet 79 | 80 | #endif // UTILS_STRING_H_ 81 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/thread_pool.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Jakob Progsch, Václav Zeman 2 | 3 | // This software is provided 'as-is', without any express or implied 4 | // warranty. In no event will the authors be held liable for any damages 5 | // arising from the use of this software. 6 | 7 | // Permission is granted to anyone to use this software for any purpose, 8 | // including commercial applications, and to alter it and redistribute it 9 | // freely, subject to the following restrictions: 10 | 11 | // 1. The origin of this software must not be misrepresented; you must not 12 | // claim that you wrote the original software. If you use this software 13 | // in a product, an acknowledgment in the product documentation would be 14 | // appreciated but is not required. 15 | 16 | // 2. Altered source versions must be plainly marked as such, and must not be 17 | // misrepresented as being the original software. 18 | 19 | // 3. This notice may not be removed or altered from any source 20 | // distribution. 21 | 22 | #ifndef UTILS_THREAD_POOL_H_ 23 | #define UTILS_THREAD_POOL_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | class ThreadPool { 37 | public: 38 | explicit ThreadPool(size_t); 39 | template 40 | auto enqueue(F&& f, Args&&... args) 41 | -> std::future::type>; 42 | ~ThreadPool(); 43 | 44 | private: 45 | // need to keep track of threads so we can join them 46 | std::vector workers; 47 | // the task queue 48 | std::queue > tasks; 49 | 50 | // synchronization 51 | std::mutex queue_mutex; 52 | std::condition_variable condition; 53 | bool stop; 54 | }; 55 | 56 | // the constructor just launches some amount of workers 57 | inline ThreadPool::ThreadPool(size_t threads) : stop(false) { 58 | for (size_t i = 0; i < threads; ++i) 59 | workers.emplace_back([this] { 60 | for (;;) { 61 | std::function task; 62 | 63 | { 64 | std::unique_lock lock(this->queue_mutex); 65 | this->condition.wait( 66 | lock, [this] { return this->stop || !this->tasks.empty(); }); 67 | if (this->stop && this->tasks.empty()) return; 68 | task = std::move(this->tasks.front()); 69 | this->tasks.pop(); 70 | } 71 | 72 | task(); 73 | } 74 | }); 75 | } 76 | 77 | // add new work item to the pool 78 | template 79 | auto ThreadPool::enqueue(F&& f, Args&&... args) 80 | -> std::future::type> { 81 | using return_type = typename std::result_of::type; 82 | 83 | auto task = std::make_shared >( 84 | std::bind(std::forward(f), std::forward(args)...)); 85 | 86 | std::future res = task->get_future(); 87 | { 88 | std::unique_lock lock(queue_mutex); 89 | 90 | // don't allow enqueueing after stopping the pool 91 | if (stop) { 92 | throw std::runtime_error("enqueue on stopped ThreadPool"); 93 | } 94 | 95 | tasks.emplace([task]() { (*task)(); }); 96 | } 97 | condition.notify_one(); 98 | return res; 99 | } 100 | 101 | // the destructor joins all threads 102 | inline ThreadPool::~ThreadPool() { 103 | { 104 | std::unique_lock lock(queue_mutex); 105 | stop = true; 106 | } 107 | condition.notify_all(); 108 | for (std::thread& worker : workers) { 109 | worker.join(); 110 | } 111 | } 112 | 113 | #endif // UTILS_THREAD_POOL_H_ 114 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/timer.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_TIMER_H_ 16 | #define UTILS_TIMER_H_ 17 | 18 | #include 19 | 20 | namespace wenet { 21 | 22 | class Timer { 23 | public: 24 | Timer() : time_start_(std::chrono::steady_clock::now()) {} 25 | void Reset() { time_start_ = std::chrono::steady_clock::now(); } 26 | // return int in milliseconds 27 | int Elapsed() const { 28 | auto time_now = std::chrono::steady_clock::now(); 29 | return std::chrono::duration_cast(time_now - 30 | time_start_) 31 | .count(); 32 | } 33 | 34 | private: 35 | std::chrono::time_point time_start_; 36 | }; 37 | } // namespace wenet 38 | 39 | #endif // UTILS_TIMER_H_ 40 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/utils.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2021 Mobvoi Inc (Zhendong Peng) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "utils/utils.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "utils/log.h" 25 | 26 | namespace wenet { 27 | 28 | float LogAdd(float x, float y) { 29 | static float num_min = -std::numeric_limits::max(); 30 | if (x <= num_min) return y; 31 | if (y <= num_min) return x; 32 | float xmax = std::max(x, y); 33 | return std::log(std::exp(x - xmax) + std::exp(y - xmax)) + xmax; 34 | } 35 | 36 | template 37 | struct ValueComp { 38 | bool operator()(const std::pair& lhs, 39 | const std::pair& rhs) const { 40 | return lhs.first > rhs.first || 41 | (lhs.first == rhs.first && lhs.second < rhs.second); 42 | } 43 | }; 44 | 45 | // We refer the pytorch topk implementation 46 | // https://github.com/pytorch/pytorch/blob/master/caffe2/operators/top_k.cc 47 | template 48 | void TopK(const std::vector& data, int32_t k, std::vector* values, 49 | std::vector* indices) { 50 | std::vector> heap_data; 51 | int n = data.size(); 52 | for (int32_t i = 0; i < k && i < n; ++i) { 53 | heap_data.emplace_back(data[i], i); 54 | } 55 | std::priority_queue, std::vector>, 56 | ValueComp> 57 | pq(ValueComp(), std::move(heap_data)); 58 | for (int32_t i = k; i < n; ++i) { 59 | if (pq.top().first < data[i]) { 60 | pq.pop(); 61 | pq.emplace(data[i], i); 62 | } 63 | } 64 | 65 | values->resize(std::min(k, n)); 66 | indices->resize(std::min(k, n)); 67 | int32_t cur = values->size() - 1; 68 | while (!pq.empty()) { 69 | const auto& item = pq.top(); 70 | (*values)[cur] = item.first; 71 | (*indices)[cur] = item.second; 72 | pq.pop(); 73 | cur -= 1; 74 | } 75 | } 76 | 77 | template void TopK(const std::vector& data, int32_t k, 78 | std::vector* values, 79 | std::vector* indices); 80 | 81 | } // namespace wenet 82 | -------------------------------------------------------------------------------- /android/src/main/cpp/utils/utils.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Mobvoi Inc (Binbin Zhang) 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef UTILS_UTILS_H_ 16 | #define UTILS_UTILS_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace wenet { 23 | 24 | #define WENET_DISALLOW_COPY_AND_ASSIGN(Type) \ 25 | Type(const Type&) = delete; \ 26 | Type& operator=(const Type&) = delete; 27 | 28 | const float kFloatMax = std::numeric_limits::max(); 29 | // kSpaceSymbol in UTF-8 is: ▁ 30 | const char kSpaceSymbol[] = "\xe2\x96\x81"; 31 | 32 | // Return the sum of two probabilities in log scale 33 | float LogAdd(float x, float y); 34 | 35 | template 36 | void TopK(const std::vector& data, int32_t k, std::vector* values, 37 | std::vector* indices); 38 | 39 | } // namespace wenet 40 | 41 | #endif // UTILS_UTILS_H_ 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativewenet/WenetModule.java: -------------------------------------------------------------------------------- 1 | package com.reactnativewenet; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.facebook.react.bridge.Promise; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 8 | import com.facebook.react.bridge.ReactMethod; 9 | import com.facebook.react.module.annotations.ReactModule; 10 | import com.facebook.react.modules.core.DeviceEventManagerModule; 11 | 12 | //Utils 13 | import android.util.Log; 14 | //Exceptions 15 | import java.io.IOException; 16 | import java.io.File; 17 | 18 | //Wenet Utils: 19 | import com.reactnativewenet.wenet.*; 20 | 21 | @ReactModule(name = WenetModule.NAME) 22 | public class WenetModule extends ReactContextBaseJavaModule { 23 | public static final String NAME = "Wenet"; 24 | private final String TAG = "Wenet"; 25 | private final ReactApplicationContext reactContext; 26 | private DeviceEventManagerModule.RCTDeviceEventEmitter eventEmitter; 27 | private Throwable failed; 28 | 29 | AudioEncoderOffline mEncoderOffline; 30 | AudioSoftwarePollerOffline audioPollerOffline; 31 | OfflineRecognition offlineSTT; 32 | 33 | public WenetModule(ReactApplicationContext reactContext) { 34 | super(reactContext); 35 | this.reactContext = reactContext; 36 | } 37 | 38 | @Override 39 | @NonNull 40 | public String getName() { 41 | return NAME; 42 | } 43 | 44 | /** 45 | * Start The event emitter 46 | * See https://reactnative.dev/docs/native-modules-android 47 | */ 48 | @ReactMethod 49 | public void setupSTT() { 50 | eventEmitter = reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class); 51 | } 52 | 53 | /** 54 | * Easy mode for wenet-stt without any of the Audio Compression using media 55 | * recorder 56 | */ 57 | @ReactMethod 58 | public void start() { 59 | offlineSTT = new OfflineRecognition(getReactApplicationContext(), eventEmitter); 60 | offlineSTT.toggleRecording(true); 61 | } 62 | 63 | @ReactMethod 64 | public void stop(Promise promise) { 65 | eventEmitter.emit("onRecordingStateChange", false); 66 | // Stops Encoder 67 | offlineSTT.toggleRecording(false); 68 | promise.resolve("TodoSendBackFilePath"); 69 | } 70 | 71 | // @ReactMethod 72 | // public void stop(Promise promise) { 73 | // eventEmitter.emit("onRecordingStateChange", false); 74 | // // Stops Encoder 75 | // if (mEncoderOffline != null) { 76 | // audioPollerOffline.stopPolling(); 77 | // String FilePath = mEncoderOffline.stop(); 78 | // promise.resolve(FilePath); 79 | // } 80 | // } 81 | 82 | @ReactMethod 83 | public void pause() { 84 | audioPollerOffline.togglePause(); 85 | } 86 | 87 | @ReactMethod 88 | public void deleteAudio(String FilePath, Promise promise) { 89 | FilePath = FilePath.replace("file://", ""); // Use getAbsolute url? 90 | File file = new File(FilePath); 91 | try { 92 | file.delete(); 93 | promise.resolve("File was deleted successfully"); 94 | } catch (Exception e) { 95 | Log.e(TAG, "Exception: ", e); 96 | promise.reject("Delete error:", e.getMessage()); 97 | } 98 | } 99 | 100 | /** 101 | * Offline stt-wenet implementation for android 102 | * 103 | * @param Filename 104 | */ 105 | @ReactMethod 106 | public void startOffline(String FileName) { 107 | eventEmitter.emit("onRecordingStateChange", true); 108 | // Start the recording 109 | mEncoderOffline = new AudioEncoderOffline(getReactApplicationContext(), FileName); 110 | audioPollerOffline = new AudioSoftwarePollerOffline(getReactApplicationContext(), eventEmitter); 111 | audioPollerOffline.setAudioEncoder(mEncoderOffline); 112 | audioPollerOffline.initOfflineDecoding(); // Can probably remove 113 | mEncoderOffline.setAudioSoftwarePoller(audioPollerOffline); 114 | audioPollerOffline.startPolling(); 115 | eventEmitter.emit("onConnectionStateChange", "ready"); // Move to encoder maybe 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativewenet/WenetPackage.java: -------------------------------------------------------------------------------- 1 | package com.reactnativewenet; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.bridge.NativeModule; 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ViewManager; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class WenetPackage implements ReactPackage { 15 | @NonNull 16 | @Override 17 | public List createNativeModules(@NonNull ReactApplicationContext reactContext) { 18 | List modules = new ArrayList<>(); 19 | modules.add(new WenetModule(reactContext)); 20 | return modules; 21 | } 22 | 23 | @NonNull 24 | @Override 25 | public List createViewManagers(@NonNull ReactApplicationContext reactContext) { 26 | return Collections.emptyList(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativewenet/wenet/Recognize.java: -------------------------------------------------------------------------------- 1 | package com.reactnativewenet.wenet; 2 | 3 | public class Recognize { 4 | 5 | static { 6 | System.loadLibrary("wenet"); // get the wenet library 7 | } 8 | 9 | public static native void init(String modelDir); 10 | 11 | public static native void reset(); 12 | 13 | public static native void acceptWaveform(short[] waveform); 14 | 15 | public static native void setInputFinished(); 16 | 17 | public static native boolean getFinished(); 18 | 19 | public static native void startDecode(); 20 | 21 | public static native String getResult(); 22 | } 23 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.4 2 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '2.7.4' 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2' 7 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.5) 5 | rexml 6 | activesupport (6.1.5.1) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.0) 13 | public_suffix (>= 2.0.2, < 5.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | atomos (0.1.3) 18 | claide (1.1.0) 19 | cocoapods (1.11.3) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.11.3) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 1.4.0, < 2.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.4.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 1.0, < 3.0) 36 | xcodeproj (>= 1.21.0, < 2.0) 37 | cocoapods-core (1.11.3) 38 | activesupport (>= 5.0, < 7) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (1.6.3) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.1.10) 58 | escape (0.0.4) 59 | ethon (0.15.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.15.5) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.10.0) 67 | concurrent-ruby (~> 1.0) 68 | json (2.6.1) 69 | minitest (5.15.0) 70 | molinillo (0.8.0) 71 | nanaimo (0.3.0) 72 | nap (1.1.0) 73 | netrc (0.11.0) 74 | public_suffix (4.0.7) 75 | rexml (3.2.5) 76 | ruby-macho (2.5.1) 77 | typhoeus (1.4.0) 78 | ethon (>= 0.9.0) 79 | tzinfo (2.0.4) 80 | concurrent-ruby (~> 1.0) 81 | xcodeproj (1.21.0) 82 | CFPropertyList (>= 2.3.3, < 4.0) 83 | atomos (~> 0.1.3) 84 | claide (>= 1.0.2, < 2.0) 85 | colored2 (~> 3.1) 86 | nanaimo (~> 0.3.0) 87 | rexml (~> 3.2.4) 88 | zeitwerk (2.5.4) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | cocoapods (~> 1.11, >= 1.11.2) 95 | 96 | RUBY VERSION 97 | ruby 2.7.4p191 98 | 99 | BUNDLED WITH 100 | 2.2.27 101 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | -keep class com.facebook.hermes.unicode.** { *; } 13 | -keep class com.facebook.jni.** { *; } 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/com/example/reactnativewenet/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example.reactnativewenet; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin; 21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 22 | import com.facebook.react.ReactInstanceEventListener; 23 | import com.facebook.react.ReactInstanceManager; 24 | import com.facebook.react.bridge.ReactContext; 25 | import com.facebook.react.modules.network.NetworkingModule; 26 | import okhttp3.OkHttpClient; 27 | 28 | public class ReactNativeFlipper { 29 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 30 | if (FlipperUtils.shouldEnableFlipper(context)) { 31 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 32 | 33 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 34 | client.addPlugin(new ReactFlipperPlugin()); 35 | client.addPlugin(new DatabasesFlipperPlugin(context)); 36 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 37 | client.addPlugin(CrashReporterPlugin.getInstance()); 38 | 39 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 40 | NetworkingModule.setCustomClientBuilder( 41 | new NetworkingModule.CustomClientBuilder() { 42 | @Override 43 | public void apply(OkHttpClient.Builder builder) { 44 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 45 | } 46 | }); 47 | client.addPlugin(networkFlipperPlugin); 48 | client.start(); 49 | 50 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 51 | // Hence we run if after all native modules have been initialized 52 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 53 | if (reactContext == null) { 54 | reactInstanceManager.addReactInstanceEventListener( 55 | new ReactInstanceEventListener() { 56 | @Override 57 | public void onReactContextInitialized(ReactContext reactContext) { 58 | reactInstanceManager.removeReactInstanceEventListener(this); 59 | reactContext.runOnNativeModulesQueueThread( 60 | new Runnable() { 61 | @Override 62 | public void run() { 63 | client.addPlugin(new FrescoFlipperPlugin()); 64 | } 65 | }); 66 | } 67 | }); 68 | } else { 69 | client.addPlugin(new FrescoFlipperPlugin()); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/reactnativewenet/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.reactnativewenet; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.ReactRootView; 6 | 7 | public class MainActivity extends ReactActivity { 8 | 9 | /** 10 | * Returns the name of the main component registered from JavaScript. This is used to schedule 11 | * rendering of the component. 12 | */ 13 | @Override 14 | protected String getMainComponentName() { 15 | return "main"; 16 | } 17 | 18 | /** 19 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and 20 | * you can specify the rendered you wish to use (Fabric or the older renderer). 21 | */ 22 | @Override 23 | protected ReactActivityDelegate createReactActivityDelegate() { 24 | return new MainActivityDelegate(this, getMainComponentName()); 25 | } 26 | 27 | public static class MainActivityDelegate extends ReactActivityDelegate { 28 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) { 29 | super(activity, mainComponentName); 30 | } 31 | 32 | @Override 33 | protected ReactRootView createRootView() { 34 | ReactRootView reactRootView = new ReactRootView(getContext()); 35 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 36 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); 37 | return reactRootView; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/reactnativewenet/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.reactnativewenet; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactInstanceManager; 8 | import com.facebook.react.ReactNativeHost; 9 | import com.facebook.react.ReactPackage; 10 | import com.facebook.react.config.ReactFeatureFlags; 11 | import com.facebook.soloader.SoLoader; 12 | import com.example.reactnativewenet.newarchitecture.MainApplicationReactNativeHost; 13 | import java.lang.reflect.InvocationTargetException; 14 | import java.util.List; 15 | 16 | public class MainApplication extends Application implements ReactApplication { 17 | 18 | private final ReactNativeHost mReactNativeHost = 19 | new ReactNativeHost(this) { 20 | @Override 21 | public boolean getUseDeveloperSupport() { 22 | return BuildConfig.DEBUG; 23 | } 24 | 25 | @Override 26 | protected List getPackages() { 27 | @SuppressWarnings("UnnecessaryLocalVariable") 28 | List packages = new PackageList(this).getPackages(); 29 | // Packages that cannot be autolinked yet can be added manually here, for example: 30 | // packages.add(new MyReactNativePackage()); 31 | return packages; 32 | } 33 | 34 | @Override 35 | protected String getJSMainModuleName() { 36 | return "index"; 37 | } 38 | }; 39 | 40 | private final ReactNativeHost mNewArchitectureNativeHost = 41 | new MainApplicationReactNativeHost(this); 42 | 43 | @Override 44 | public ReactNativeHost getReactNativeHost() { 45 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 46 | return mNewArchitectureNativeHost; 47 | } else { 48 | return mReactNativeHost; 49 | } 50 | } 51 | 52 | @Override 53 | public void onCreate() { 54 | super.onCreate(); 55 | // If you opted-in for the New Architecture, we enable the TurboModule system 56 | ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 57 | SoLoader.init(this, /* native exopackage */ false); 58 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 59 | } 60 | 61 | /** 62 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like 63 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 64 | * 65 | * @param context 66 | * @param reactInstanceManager 67 | */ 68 | private static void initializeFlipper( 69 | Context context, ReactInstanceManager reactInstanceManager) { 70 | if (BuildConfig.DEBUG) { 71 | try { 72 | /* 73 | We use reflection here to pick up the class that initializes Flipper, 74 | since Flipper library is not available in release mode 75 | */ 76 | Class aClass = Class.forName("com.example.reactnativewenet.ReactNativeFlipper"); 77 | aClass 78 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) 79 | .invoke(null, context, reactInstanceManager); 80 | } catch (ClassNotFoundException e) { 81 | e.printStackTrace(); 82 | } catch (NoSuchMethodException e) { 83 | e.printStackTrace(); 84 | } catch (IllegalAccessException e) { 85 | e.printStackTrace(); 86 | } catch (InvocationTargetException e) { 87 | e.printStackTrace(); 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/reactnativewenet/newarchitecture/components/MainComponentsRegistry.java: -------------------------------------------------------------------------------- 1 | package com.example.reactnativewenet.newarchitecture.components; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.proguard.annotations.DoNotStrip; 5 | import com.facebook.react.fabric.ComponentFactory; 6 | import com.facebook.soloader.SoLoader; 7 | 8 | /** 9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a 10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 11 | * folder for you). 12 | * 13 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 14 | * `newArchEnabled` property). Is ignored otherwise. 15 | */ 16 | @DoNotStrip 17 | public class MainComponentsRegistry { 18 | static { 19 | SoLoader.loadLibrary("fabricjni"); 20 | } 21 | 22 | @DoNotStrip private final HybridData mHybridData; 23 | 24 | @DoNotStrip 25 | private native HybridData initHybrid(ComponentFactory componentFactory); 26 | 27 | @DoNotStrip 28 | private MainComponentsRegistry(ComponentFactory componentFactory) { 29 | mHybridData = initHybrid(componentFactory); 30 | } 31 | 32 | @DoNotStrip 33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) { 34 | return new MainComponentsRegistry(componentFactory); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/reactnativewenet/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java: -------------------------------------------------------------------------------- 1 | package com.example.reactnativewenet.newarchitecture.modules; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.react.ReactPackage; 5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.soloader.SoLoader; 8 | import java.util.List; 9 | 10 | /** 11 | * Class responsible to load the TurboModules. This class has native methods and needs a 12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 13 | * folder for you). 14 | * 15 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 16 | * `newArchEnabled` property). Is ignored otherwise. 17 | */ 18 | public class MainApplicationTurboModuleManagerDelegate 19 | extends ReactPackageTurboModuleManagerDelegate { 20 | 21 | private static volatile boolean sIsSoLibraryLoaded; 22 | 23 | protected MainApplicationTurboModuleManagerDelegate( 24 | ReactApplicationContext reactApplicationContext, List packages) { 25 | super(reactApplicationContext, packages); 26 | } 27 | 28 | protected native HybridData initHybrid(); 29 | 30 | native boolean canCreateTurboModule(String moduleName); 31 | 32 | public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { 33 | protected MainApplicationTurboModuleManagerDelegate build( 34 | ReactApplicationContext context, List packages) { 35 | return new MainApplicationTurboModuleManagerDelegate(context, packages); 36 | } 37 | } 38 | 39 | @Override 40 | protected synchronized void maybeLoadOtherSoLibraries() { 41 | if (!sIsSoLibraryLoaded) { 42 | // If you change the name of your application .so file in the Android.mk file, 43 | // make sure you update the name here as well. 44 | SoLoader.loadLibrary("example_appmodules"); 45 | sIsSoLibraryLoaded = true; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | THIS_DIR := $(call my-dir) 2 | 3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk 4 | 5 | # If you wish to add a custom TurboModule or Fabric component in your app you 6 | # will have to include the following autogenerated makefile. 7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk 8 | include $(CLEAR_VARS) 9 | 10 | LOCAL_PATH := $(THIS_DIR) 11 | 12 | # You can customize the name of your application .so file here. 13 | LOCAL_MODULE := example_appmodules 14 | 15 | LOCAL_C_INCLUDES := $(LOCAL_PATH) 16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) 17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) 18 | 19 | # If you wish to add a custom TurboModule or Fabric component in your app you 20 | # will have to uncomment those lines to include the generated source 21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) 22 | # 23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) 25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 26 | 27 | # Here you should add any native library you wish to depend on. 28 | LOCAL_SHARED_LIBRARIES := \ 29 | libfabricjni \ 30 | libfbjni \ 31 | libfolly_futures \ 32 | libfolly_json \ 33 | libglog \ 34 | libjsi \ 35 | libreact_codegen_rncore \ 36 | libreact_debug \ 37 | libreact_nativemodule_core \ 38 | libreact_render_componentregistry \ 39 | libreact_render_core \ 40 | libreact_render_debug \ 41 | libreact_render_graphics \ 42 | librrc_view \ 43 | libruntimeexecutor \ 44 | libturbomodulejsijni \ 45 | libyoga 46 | 47 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall 48 | 49 | include $(BUILD_SHARED_LIBRARY) 50 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationModuleProvider.h" 2 | 3 | #include 4 | 5 | namespace facebook { 6 | namespace react { 7 | 8 | std::shared_ptr MainApplicationModuleProvider( 9 | const std::string moduleName, 10 | const JavaTurboModule::InitParams ¶ms) { 11 | // Here you can provide your own module provider for TurboModules coming from 12 | // either your application or from external libraries. The approach to follow 13 | // is similar to the following (for a library called `samplelibrary`: 14 | // 15 | // auto module = samplelibrary_ModuleProvider(moduleName, params); 16 | // if (module != nullptr) { 17 | // return module; 18 | // } 19 | // return rncore_ModuleProvider(moduleName, params); 20 | 21 | 22 | return rncore_ModuleProvider(moduleName, params); 23 | } 24 | 25 | } // namespace react 26 | } // namespace facebook 27 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | std::shared_ptr MainApplicationModuleProvider( 12 | const std::string moduleName, 13 | const JavaTurboModule::InitParams ¶ms); 14 | 15 | } // namespace react 16 | } // namespace facebook 17 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationTurboModuleManagerDelegate.h" 2 | #include "MainApplicationModuleProvider.h" 3 | 4 | namespace facebook { 5 | namespace react { 6 | 7 | jni::local_ref 8 | MainApplicationTurboModuleManagerDelegate::initHybrid( 9 | jni::alias_ref) { 10 | return makeCxxInstance(); 11 | } 12 | 13 | void MainApplicationTurboModuleManagerDelegate::registerNatives() { 14 | registerHybrid({ 15 | makeNativeMethod( 16 | "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), 17 | makeNativeMethod( 18 | "canCreateTurboModule", 19 | MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), 20 | }); 21 | } 22 | 23 | std::shared_ptr 24 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 25 | const std::string name, 26 | const std::shared_ptr jsInvoker) { 27 | // Not implemented yet: provide pure-C++ NativeModules here. 28 | return nullptr; 29 | } 30 | 31 | std::shared_ptr 32 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 33 | const std::string name, 34 | const JavaTurboModule::InitParams ¶ms) { 35 | return MainApplicationModuleProvider(name, params); 36 | } 37 | 38 | bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( 39 | std::string name) { 40 | return getTurboModule(name, nullptr) != nullptr || 41 | getTurboModule(name, {.moduleName = name}) != nullptr; 42 | } 43 | 44 | } // namespace react 45 | } // namespace facebook 46 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | namespace facebook { 8 | namespace react { 9 | 10 | class MainApplicationTurboModuleManagerDelegate 11 | : public jni::HybridClass< 12 | MainApplicationTurboModuleManagerDelegate, 13 | TurboModuleManagerDelegate> { 14 | public: 15 | // Adapt it to the package you used for your Java class. 16 | static constexpr auto kJavaDescriptor = 17 | "Lcom/example/reactnativewenet/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; 18 | 19 | static jni::local_ref initHybrid(jni::alias_ref); 20 | 21 | static void registerNatives(); 22 | 23 | std::shared_ptr getTurboModule( 24 | const std::string name, 25 | const std::shared_ptr jsInvoker) override; 26 | std::shared_ptr getTurboModule( 27 | const std::string name, 28 | const JavaTurboModule::InitParams ¶ms) override; 29 | 30 | /** 31 | * Test-only method. Allows user to verify whether a TurboModule can be 32 | * created by instances of this class. 33 | */ 34 | bool canCreateTurboModule(std::string name); 35 | }; 36 | 37 | } // namespace react 38 | } // namespace facebook 39 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainComponentsRegistry.cpp: -------------------------------------------------------------------------------- 1 | #include "MainComponentsRegistry.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} 12 | 13 | std::shared_ptr 14 | MainComponentsRegistry::sharedProviderRegistry() { 15 | auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); 16 | 17 | // Custom Fabric Components go here. You can register custom 18 | // components coming from your App or from 3rd party libraries here. 19 | // 20 | // providerRegistry->add(concreteComponentDescriptorProvider< 21 | // AocViewerComponentDescriptor>()); 22 | return providerRegistry; 23 | } 24 | 25 | jni::local_ref 26 | MainComponentsRegistry::initHybrid( 27 | jni::alias_ref, 28 | ComponentFactory *delegate) { 29 | auto instance = makeCxxInstance(delegate); 30 | 31 | auto buildRegistryFunction = 32 | [](EventDispatcher::Weak const &eventDispatcher, 33 | ContextContainer::Shared const &contextContainer) 34 | -> ComponentDescriptorRegistry::Shared { 35 | auto registry = MainComponentsRegistry::sharedProviderRegistry() 36 | ->createComponentDescriptorRegistry( 37 | {eventDispatcher, contextContainer}); 38 | 39 | auto mutableRegistry = 40 | std::const_pointer_cast(registry); 41 | 42 | mutableRegistry->setFallbackComponentDescriptor( 43 | std::make_shared( 44 | ComponentDescriptorParameters{ 45 | eventDispatcher, contextContainer, nullptr})); 46 | 47 | return registry; 48 | }; 49 | 50 | delegate->buildRegistryFunction = buildRegistryFunction; 51 | return instance; 52 | } 53 | 54 | void MainComponentsRegistry::registerNatives() { 55 | registerHybrid({ 56 | makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), 57 | }); 58 | } 59 | 60 | } // namespace react 61 | } // namespace facebook 62 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainComponentsRegistry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | class MainComponentsRegistry 12 | : public facebook::jni::HybridClass { 13 | public: 14 | // Adapt it to the package you used for your Java class. 15 | constexpr static auto kJavaDescriptor = 16 | "Lcom/example/reactnativewenet/newarchitecture/components/MainComponentsRegistry;"; 17 | 18 | static void registerNatives(); 19 | 20 | MainComponentsRegistry(ComponentFactory *delegate); 21 | 22 | private: 23 | static std::shared_ptr 24 | sharedProviderRegistry(); 25 | 26 | static jni::local_ref initHybrid( 27 | jni::alias_ref, 28 | ComponentFactory *delegate); 29 | }; 30 | 31 | } // namespace react 32 | } // namespace facebook 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/OnLoad.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "MainApplicationTurboModuleManagerDelegate.h" 3 | #include "MainComponentsRegistry.h" 4 | 5 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { 6 | return facebook::jni::initialize(vm, [] { 7 | facebook::react::MainApplicationTurboModuleManagerDelegate:: 8 | registerNatives(); 9 | facebook::react::MainComponentsRegistry::registerNatives(); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | React Native Wenet Example 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | import org.apache.tools.ant.taskdefs.condition.Os 2 | 3 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 4 | 5 | buildscript { 6 | ext { 7 | buildToolsVersion = "31.0.0" 8 | minSdkVersion = 21 9 | compileSdkVersion = 31 10 | targetSdkVersion = 31 11 | 12 | if (System.properties['os.arch'] == "aarch64") { 13 | // For M1 Users we need to use the NDK 24 which added support for aarch64 14 | ndkVersion = "24.0.8215888" 15 | } else { 16 | // Otherwise we default to the side-by-side NDK version from AGP. 17 | ndkVersion = "21.4.7075529" 18 | } 19 | } 20 | repositories { 21 | google() 22 | mavenCentral() 23 | } 24 | dependencies { 25 | classpath("com.android.tools.build:gradle:7.0.4") 26 | classpath("com.facebook.react:react-native-gradle-plugin") 27 | classpath("de.undercouch:gradle-download-task:4.1.2") 28 | // NOTE: Do not place your application dependencies here; they belong 29 | // in the individual module build.gradle files 30 | } 31 | } 32 | 33 | allprojects { 34 | repositories { 35 | maven { 36 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 37 | url("$rootDir/../node_modules/react-native/android") 38 | } 39 | maven { 40 | // Android JSC is installed from npm 41 | url("$rootDir/../node_modules/jsc-android/dist") 42 | } 43 | mavenCentral { 44 | // We don't want to fetch react-native from Maven Central as there are 45 | // older versions over there. 46 | content { 47 | excludeGroup "com.facebook.react" 48 | } 49 | } 50 | google() 51 | maven { url 'https://www.jitpack.io' } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.125.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=false -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hannes1/react-native-wenet/fe5e7a06089b161ba717eb8d410795f432bd71eb/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'WenetExample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/react-native-gradle-plugin') 5 | 6 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { 7 | include(":ReactAndroid") 8 | project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') 9 | } 10 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | presets: ['module:metro-react-native-babel-preset'], 6 | plugins: [ 7 | [ 8 | 'module-resolver', 9 | { 10 | extensions: ['.tsx', '.ts', '.js', '.json'], 11 | alias: { 12 | [pak.name]: path.join(__dirname, '..', pak.source), 13 | }, 14 | }, 15 | ], 16 | ], 17 | }; 18 | -------------------------------------------------------------------------------- /example/index.tsx: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './src/App'; 3 | 4 | AppRegistry.registerComponent('main', () => App); 5 | -------------------------------------------------------------------------------- /example/ios/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // WenetExample 4 | // 5 | 6 | import Foundation 7 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '11.0' 5 | install! 'cocoapods', :deterministic_uuids => false 6 | 7 | ENV['RCT_NEW_ARCH_ENABLED'] = '0' 8 | 9 | target 'WenetExample' do 10 | config = use_native_modules! 11 | 12 | # Flags change depending on the env values. 13 | flags = get_default_flags() 14 | 15 | use_react_native!( 16 | :path => config[:reactNativePath], 17 | # to enable hermes on iOS, change `false` to `true` and then install pods 18 | :hermes_enabled => true, 19 | :fabric_enabled => flags[:fabric_enabled], 20 | # An absolute path to your application root. 21 | :app_path => "#{Pod::Config.instance.installation_root}/.." 22 | ) 23 | 24 | # Enables Flipper. 25 | # 26 | # Note that if you have use_frameworks! enabled, Flipper will not work and 27 | # you should disable the next line. 28 | use_flipper!() 29 | 30 | post_install do |installer| 31 | react_native_post_install(installer) 32 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /example/ios/WenetExample-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /example/ios/WenetExample.xcodeproj/xcshareddata/xcschemes/WenetExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 35 | 37 | 43 | 44 | 45 | 46 | 52 | 54 | 60 | 61 | 62 | 63 | 65 | 66 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /example/ios/WenetExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/WenetExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/WenetExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /example/ios/WenetExample/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | #import 6 | 7 | #import 8 | 9 | #if RCT_NEW_ARCH_ENABLED 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | #import 18 | 19 | @interface AppDelegate () { 20 | RCTTurboModuleManager *_turboModuleManager; 21 | RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; 22 | std::shared_ptr _reactNativeConfig; 23 | facebook::react::ContextContainer::Shared _contextContainer; 24 | } 25 | @end 26 | #endif 27 | 28 | @implementation AppDelegate 29 | 30 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 31 | { 32 | RCTAppSetupPrepareApp(application); 33 | 34 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 35 | 36 | #if RCT_NEW_ARCH_ENABLED 37 | _contextContainer = std::make_shared(); 38 | _reactNativeConfig = std::make_shared(); 39 | _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); 40 | _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; 41 | bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; 42 | #endif 43 | 44 | UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"main", nil); 45 | 46 | if (@available(iOS 13.0, *)) { 47 | rootView.backgroundColor = [UIColor systemBackgroundColor]; 48 | } else { 49 | rootView.backgroundColor = [UIColor whiteColor]; 50 | } 51 | 52 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 53 | UIViewController *rootViewController = [UIViewController new]; 54 | rootViewController.view = rootView; 55 | self.window.rootViewController = rootViewController; 56 | [self.window makeKeyAndVisible]; 57 | return YES; 58 | } 59 | 60 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 61 | { 62 | #if DEBUG 63 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 64 | #else 65 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 66 | #endif 67 | } 68 | 69 | #if RCT_NEW_ARCH_ENABLED 70 | 71 | #pragma mark - RCTCxxBridgeDelegate 72 | 73 | - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge 74 | { 75 | _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge 76 | delegate:self 77 | jsInvoker:bridge.jsCallInvoker]; 78 | return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager); 79 | } 80 | 81 | #pragma mark RCTTurboModuleManagerDelegate 82 | 83 | - (Class)getModuleClassFromName:(const char *)name 84 | { 85 | return RCTCoreModulesClassProvider(name); 86 | } 87 | 88 | - (std::shared_ptr)getTurboModule:(const std::string &)name 89 | jsInvoker:(std::shared_ptr)jsInvoker 90 | { 91 | return nullptr; 92 | } 93 | 94 | - (std::shared_ptr)getTurboModule:(const std::string &)name 95 | initParams: 96 | (const facebook::react::ObjCTurboModule::InitParams &)params 97 | { 98 | return nullptr; 99 | } 100 | 101 | - (id)getModuleInstanceFromClass:(Class)moduleClass 102 | { 103 | return RCTAppSetupDefaultModuleFromClass(moduleClass); 104 | } 105 | 106 | #endif 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /example/ios/WenetExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/ios/WenetExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/WenetExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /example/ios/WenetExample/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const escape = require('escape-string-regexp'); 3 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 4 | const pak = require('../package.json'); 5 | 6 | const root = path.resolve(__dirname, '..'); 7 | 8 | const modules = Object.keys({ 9 | ...pak.peerDependencies, 10 | }); 11 | 12 | module.exports = { 13 | projectRoot: __dirname, 14 | watchFolders: [root], 15 | 16 | // We need to make sure that only one version is loaded for peerDependencies 17 | // So we block them at the root, and alias them to the versions in example's node_modules 18 | resolver: { 19 | blacklistRE: exclusionList( 20 | modules.map( 21 | (m) => 22 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) 23 | ) 24 | ), 25 | 26 | extraNodeModules: modules.reduce((acc, name) => { 27 | acc[name] = path.join(__dirname, 'node_modules', name); 28 | return acc; 29 | }, {}), 30 | }, 31 | 32 | transformer: { 33 | getTransformOptions: async () => ({ 34 | transform: { 35 | experimentalImportSupport: false, 36 | inlineRequires: true, 37 | }, 38 | }), 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-wenet-example", 3 | "description": "Example app for react-native-wenet", 4 | "version": "0.0.1", 5 | "private": true, 6 | "scripts": { 7 | "android": "react-native run-android", 8 | "ios": "react-native run-ios", 9 | "start": "react-native start", 10 | "pods": "pod-install --quiet", 11 | "postinstall": "patch-package" 12 | }, 13 | "dependencies": { 14 | "react": "17.0.2", 15 | "react-native": "0.68.2", 16 | "react-native-permissions": "^3.6.1", 17 | "react-native-vector-icons": "^9.2.0" 18 | }, 19 | "devDependencies": { 20 | "@babel/core": "^7.12.10", 21 | "@babel/runtime": "^7.12.5", 22 | "@types/react-native-vector-icons": "^6.4.12", 23 | "babel-plugin-module-resolver": "^4.1.0", 24 | "metro-react-native-babel-preset": "^0.67.0", 25 | "patch-package": "^6.4.7", 26 | "postinstall-postinstall": "^2.1.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | dependencies: { 5 | 'react-native-wenet': { 6 | root: path.join(__dirname, '..'), 7 | }, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { StyleSheet, View, Text, Button } from 'react-native'; 4 | import Wenet, { Event } from 'react-native-wenet'; 5 | import { request, PERMISSIONS } from 'react-native-permissions'; 6 | 7 | export default function App() { 8 | const [result, setResult] = React.useState('No Results Yet'); 9 | 10 | React.useEffect(() => { 11 | Wenet.setupSTT(); 12 | request(PERMISSIONS.ANDROID.RECORD_AUDIO).then((r) => { 13 | console.log('🚀 ~ file: App.tsx ~ line 17 ~ request ~ result', r); 14 | // … 15 | }); 16 | }, []); 17 | 18 | const handleStart = async () => { 19 | //await Audio.requestPermissionsAsync(); 20 | setResult(''); 21 | Wenet.startSTT(); 22 | Wenet.addEventListener(Event.Result, (data) => { 23 | setResult(data); 24 | }); 25 | }; 26 | 27 | const handleStop = async () => { 28 | Wenet.stopSTT(); 29 | }; 30 | 31 | return ( 32 | 33 | {/* */} 34 | handleStart()}> 35 | Result: {result} 36 | 37 | 38 |