Committed by
GitHub
Publish `sherpa_onnx.har` for HarmonyOS (#1572)
正在显示
100 个修改的文件
包含
1854 行增加
和
8 行删除
.github/workflows/har.yaml
0 → 100644
| 1 | +name: har | ||
| 2 | + | ||
| 3 | +on: | ||
| 4 | + push: | ||
| 5 | + branches: | ||
| 6 | + - master | ||
| 7 | + # - ohos-har | ||
| 8 | + tags: | ||
| 9 | + - 'v[0-9]+.[0-9]+.[0-9]+*' | ||
| 10 | + | ||
| 11 | + workflow_dispatch: | ||
| 12 | + | ||
| 13 | +concurrency: | ||
| 14 | + group: har-${{ github.ref }} | ||
| 15 | + cancel-in-progress: true | ||
| 16 | + | ||
| 17 | +jobs: | ||
| 18 | + har: | ||
| 19 | + name: Har | ||
| 20 | + runs-on: ${{ matrix.os }} | ||
| 21 | + strategy: | ||
| 22 | + fail-fast: false | ||
| 23 | + matrix: | ||
| 24 | + os: [ubuntu-latest] | ||
| 25 | + | ||
| 26 | + steps: | ||
| 27 | + - uses: actions/checkout@v4 | ||
| 28 | + with: | ||
| 29 | + fetch-depth: 0 | ||
| 30 | + | ||
| 31 | + - name: ccache | ||
| 32 | + uses: hendrikmuhs/ccache-action@v1.2 | ||
| 33 | + with: | ||
| 34 | + key: har-linux | ||
| 35 | + | ||
| 36 | + - name: cache-toolchain | ||
| 37 | + id: cache-toolchain-ohos | ||
| 38 | + uses: actions/cache@v4 | ||
| 39 | + with: | ||
| 40 | + path: command-line-tools | ||
| 41 | + key: commandline-tools-linux-x64-5.0.5.200.zip | ||
| 42 | + | ||
| 43 | + - name: Download toolchain | ||
| 44 | + if: steps.cache-toolchain-ohos.outputs.cache-hit != 'true' | ||
| 45 | + shell: bash | ||
| 46 | + run: | | ||
| 47 | + curl -SL -O https://huggingface.co/csukuangfj/harmonyos-commandline-tools/resolve/main/commandline-tools-linux-x64-5.0.5.200.zip | ||
| 48 | + unzip commandline-tools-linux-x64-5.0.5.200.zip | ||
| 49 | + rm commandline-tools-linux-x64-5.0.5.200.zip | ||
| 50 | + | ||
| 51 | + - name: Set environment variable | ||
| 52 | + shell: bash | ||
| 53 | + run: | | ||
| 54 | + echo "$GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native/build-tools/cmake/bin" >> "$GITHUB_PATH" | ||
| 55 | + which cmake | ||
| 56 | + | ||
| 57 | + cmake --version | ||
| 58 | + | ||
| 59 | + ls -lh $GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native/build/cmake/ohos.toolchain.cmake | ||
| 60 | + | ||
| 61 | + echo "====" | ||
| 62 | + cat $GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native/build/cmake/ohos.toolchain.cmake | ||
| 63 | + echo "====" | ||
| 64 | + | ||
| 65 | + # echo "$GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native/llvm/bin" >> "$GITHUB_PATH" | ||
| 66 | + | ||
| 67 | + ls -lh $GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native/llvm/bin/ | ||
| 68 | + echo "--" | ||
| 69 | + ls -lh $GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native/llvm/bin/*unknown* | ||
| 70 | + | ||
| 71 | + cat $GITHUB_PATH | ||
| 72 | + | ||
| 73 | + # /home/runner/work/onnxruntime-libs/onnxruntime-libs/command-line-tools/sdk/default/openharmony/native/llvm/bin/aarch64-unknown-linux-ohos-clang -v || true | ||
| 74 | + export PATH=$PWD/command-line-tools/sdk/default/openharmony/native/llvm/bin:$PATH | ||
| 75 | + echo "path: $PATH" | ||
| 76 | + | ||
| 77 | + which aarch64-unknown-linux-ohos-clang++ || true | ||
| 78 | + which aarch64-unknown-linux-ohos-clang || true | ||
| 79 | + | ||
| 80 | + aarch64-unknown-linux-ohos-clang++ --version || true | ||
| 81 | + aarch64-unknown-linux-ohos-clang --version || true | ||
| 82 | + | ||
| 83 | + which armv7-unknown-linux-ohos-clang++ | ||
| 84 | + which armv7-unknown-linux-ohos-clang | ||
| 85 | + | ||
| 86 | + armv7-unknown-linux-ohos-clang++ --version | ||
| 87 | + armv7-unknown-linux-ohos-clang --version | ||
| 88 | + | ||
| 89 | + which x86_64-unknown-linux-ohos-clang++ | ||
| 90 | + which x86_64-unknown-linux-ohos-clang | ||
| 91 | + | ||
| 92 | + x86_64-unknown-linux-ohos-clang++ --version | ||
| 93 | + x86_64-unknown-linux-ohos-clang --version | ||
| 94 | + | ||
| 95 | + - name: Build libraries | ||
| 96 | + shell: bash | ||
| 97 | + run: | | ||
| 98 | + export CMAKE_CXX_COMPILER_LAUNCHER=ccache | ||
| 99 | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" | ||
| 100 | + cmake --version | ||
| 101 | + | ||
| 102 | + export OHOS_SDK_NATIVE_DIR="$GITHUB_WORKSPACE/command-line-tools/sdk/default/openharmony/native" | ||
| 103 | + | ||
| 104 | + ./build-ohos-arm64-v8a.sh | ||
| 105 | + ./build-ohos-x86-64.sh | ||
| 106 | + | ||
| 107 | + - name: Build Har | ||
| 108 | + shell: bash | ||
| 109 | + run: | | ||
| 110 | + export PATH="$GITHUB_WORKSPACE/command-line-tools/bin:$PATH" | ||
| 111 | + | ||
| 112 | + which hvigorw | ||
| 113 | + | ||
| 114 | + pushd harmony-os/SherpaOnnxHar | ||
| 115 | + | ||
| 116 | + hvigorw --mode module -p product=default -p module=sherpa_onnx@default assembleHar --analyze=normal --parallel --incremental --no-daemon | ||
| 117 | + ls -lh ./sherpa_onnx/build/default/outputs/default/sherpa_onnx.har | ||
| 118 | + cp -v ./sherpa_onnx/build/default/outputs/default/sherpa_onnx.har ../../ | ||
| 119 | + | ||
| 120 | + popd | ||
| 121 | + | ||
| 122 | + ls -lh *.har | ||
| 123 | + | ||
| 124 | + - name: Collect result | ||
| 125 | + shell: bash | ||
| 126 | + run: | | ||
| 127 | + SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2) | ||
| 128 | + echo "SHERPA_ONNX_VERSION=$SHERPA_ONNX_VERSION" >> "$GITHUB_ENV" | ||
| 129 | + | ||
| 130 | + mv sherpa_onnx.har sherpa_onnx-$SHERPA_ONNX_VERSION.har | ||
| 131 | + | ||
| 132 | + - uses: actions/upload-artifact@v4 | ||
| 133 | + with: | ||
| 134 | + name: sherpa-onnx-har | ||
| 135 | + path: ./sherpa_onnx*.har | ||
| 136 | + | ||
| 137 | + - name: Release jar | ||
| 138 | + if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') | ||
| 139 | + uses: svenstaro/upload-release-action@v2 | ||
| 140 | + with: | ||
| 141 | + file_glob: true | ||
| 142 | + overwrite: true | ||
| 143 | + file: ./*.har | ||
| 144 | + # repo_name: k2-fsa/sherpa-onnx | ||
| 145 | + # repo_token: ${{ secrets.UPLOAD_GH_SHERPA_ONNX_TOKEN }} | ||
| 146 | + # tag: v1.10.32 | ||
| 147 | + | ||
| 148 | + - name: Publish to huggingface | ||
| 149 | + if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') | ||
| 150 | + env: | ||
| 151 | + HF_TOKEN: ${{ secrets.HF_TOKEN }} | ||
| 152 | + uses: nick-fields/retry@v3 | ||
| 153 | + with: | ||
| 154 | + max_attempts: 20 | ||
| 155 | + timeout_seconds: 200 | ||
| 156 | + shell: bash | ||
| 157 | + command: | | ||
| 158 | + git config --global user.email "csukuangfj@gmail.com" | ||
| 159 | + git config --global user.name "Fangjun Kuang" | ||
| 160 | + | ||
| 161 | + rm -rf huggingface | ||
| 162 | + export GIT_LFS_SKIP_SMUDGE=1 | ||
| 163 | + export GIT_CLONE_PROTECTION_ACTIVE=false | ||
| 164 | + | ||
| 165 | + SHERPA_ONNX_VERSION=$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2) | ||
| 166 | + echo "SHERPA_ONNX_VERSION $SHERPA_ONNX_VERSION" | ||
| 167 | + | ||
| 168 | + git clone https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-harmony-os huggingface | ||
| 169 | + cd huggingface | ||
| 170 | + git fetch | ||
| 171 | + git pull | ||
| 172 | + git merge -m "merge remote" --ff origin main | ||
| 173 | + | ||
| 174 | + d=har | ||
| 175 | + mkdir -p $d | ||
| 176 | + cp -v ../*.har $d/ | ||
| 177 | + git status | ||
| 178 | + git lfs track "*.har" | ||
| 179 | + git add . | ||
| 180 | + git commit -m "add more hars" | ||
| 181 | + git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-harmony-os main |
| @@ -18,14 +18,13 @@ | @@ -18,14 +18,13 @@ | ||
| 18 | 18 | ||
| 19 | ### Supported platforms | 19 | ### Supported platforms |
| 20 | 20 | ||
| 21 | -|Architecture| Android | iOS | Windows | macOS | linux | | ||
| 22 | -|------------|---------|---------|------------|-------|-------| | ||
| 23 | -| x64 | ✔️ | | ✔️ | ✔️ | ✔️ | | ||
| 24 | -| x86 | ✔️ | | ✔️ | | | | ||
| 25 | -| arm64 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | | ||
| 26 | -| arm32 | ✔️ | | | | ✔️ | | ||
| 27 | -| riscv64 | | | | | ✔️ | | ||
| 28 | - | 21 | +|Architecture| Android | iOS | Windows | macOS | linux | HarmonyOS | |
| 22 | +|------------|---------|---------|------------|-------|-------|-----------| | ||
| 23 | +| x64 | ✔️ | | ✔️ | ✔️ | ✔️ | ✔️ | | ||
| 24 | +| x86 | ✔️ | | ✔️ | | | | | ||
| 25 | +| arm64 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | | ||
| 26 | +| arm32 | ✔️ | | | | ✔️ | ✔️ | | ||
| 27 | +| riscv64 | | | | | ✔️ | | | ||
| 29 | 28 | ||
| 30 | ### Supported programming languages | 29 | ### Supported programming languages |
| 31 | 30 | ||
| @@ -65,6 +64,7 @@ on the following platforms and operating systems: | @@ -65,6 +64,7 @@ on the following platforms and operating systems: | ||
| 65 | - Linux, macOS, Windows, openKylin | 64 | - Linux, macOS, Windows, openKylin |
| 66 | - Android, WearOS | 65 | - Android, WearOS |
| 67 | - iOS | 66 | - iOS |
| 67 | + - HarmonyOS | ||
| 68 | - NodeJS | 68 | - NodeJS |
| 69 | - WebAssembly | 69 | - WebAssembly |
| 70 | - [Raspberry Pi][Raspberry Pi] | 70 | - [Raspberry Pi][Raspberry Pi] |
| @@ -134,3 +134,9 @@ cp -fv $onnxruntime_dir/lib/libonnxruntime.so install/lib | @@ -134,3 +134,9 @@ cp -fv $onnxruntime_dir/lib/libonnxruntime.so install/lib | ||
| 134 | 134 | ||
| 135 | rm -rf install/share | 135 | rm -rf install/share |
| 136 | rm -rf install/lib/pkgconfig | 136 | rm -rf install/lib/pkgconfig |
| 137 | + | ||
| 138 | +d=../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/libs/arm64-v8a | ||
| 139 | +if [ -d $d ]; then | ||
| 140 | + cp -v install/lib/libsherpa-onnx-c-api.so $d/ | ||
| 141 | + cp -v install/lib/libonnxruntime.so $d/ | ||
| 142 | +fi |
| @@ -134,3 +134,9 @@ cp -fv $onnxruntime_dir/lib/libonnxruntime.so install/lib | @@ -134,3 +134,9 @@ cp -fv $onnxruntime_dir/lib/libonnxruntime.so install/lib | ||
| 134 | 134 | ||
| 135 | rm -rf install/share | 135 | rm -rf install/share |
| 136 | rm -rf install/lib/pkgconfig | 136 | rm -rf install/lib/pkgconfig |
| 137 | + | ||
| 138 | +d=../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/libs/x86_64 | ||
| 139 | +if [ -d $d ]; then | ||
| 140 | + cp -v install/lib/libsherpa-onnx-c-api.so $d/ | ||
| 141 | + cp -v install/lib/libonnxruntime.so $d/ | ||
| 142 | +fi |
harmony-os/.gitignore
0 → 100644
| 1 | +!build-profile.json5 |
harmony-os/SherpaOnnxHar/.gitignore
0 → 100644
harmony-os/SherpaOnnxHar/AppScope/app.json5
0 → 100644
2.7 KB
harmony-os/SherpaOnnxHar/README.md
0 → 100644
| 1 | +# Introduction | ||
| 2 | + | ||
| 3 | +How to build `sherpa_onnx.har` from the command line: | ||
| 4 | + | ||
| 5 | +```bash | ||
| 6 | +git clone https://github.com/k2-fsa/sherpa-onnx | ||
| 7 | +cd sherpa-onnx | ||
| 8 | +./build-ohos-arm64-v8a.sh | ||
| 9 | +./build-ohos-x86-64.sh | ||
| 10 | + | ||
| 11 | +cd harmony-os/SherpaOnnxHar | ||
| 12 | + | ||
| 13 | +hvigorw clean --no-daemon | ||
| 14 | + | ||
| 15 | +hvigorw --mode module -p product=default -p module=sherpa_onnx@default assembleHar --analyze=normal --parallel --incremental --no-daemon | ||
| 16 | + | ||
| 17 | +ls -lh ./sherpa_onnx/build/default/outputs/default/sherpa_onnx.har | ||
| 18 | +``` |
harmony-os/SherpaOnnxHar/build-profile.json5
0 → 100644
| 1 | +{ | ||
| 2 | + "app": { | ||
| 3 | + "signingConfigs": [], | ||
| 4 | + "products": [ | ||
| 5 | + { | ||
| 6 | + "name": "default", | ||
| 7 | + "signingConfig": "default", | ||
| 8 | + "compatibleSdkVersion": "4.0.0(10)", | ||
| 9 | + "runtimeOS": "HarmonyOS", | ||
| 10 | + "buildOption": { | ||
| 11 | + "strictMode": { | ||
| 12 | + "caseSensitiveCheck": true, | ||
| 13 | + } | ||
| 14 | + } | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "buildModeSet": [ | ||
| 18 | + { | ||
| 19 | + "name": "debug", | ||
| 20 | + }, | ||
| 21 | + { | ||
| 22 | + "name": "release" | ||
| 23 | + } | ||
| 24 | + ] | ||
| 25 | + }, | ||
| 26 | + "modules": [ | ||
| 27 | + { | ||
| 28 | + "name": "entry", | ||
| 29 | + "srcPath": "./entry", | ||
| 30 | + "targets": [ | ||
| 31 | + { | ||
| 32 | + "name": "default", | ||
| 33 | + "applyToProducts": [ | ||
| 34 | + "default" | ||
| 35 | + ] | ||
| 36 | + } | ||
| 37 | + ] | ||
| 38 | + }, | ||
| 39 | + { | ||
| 40 | + "name": "sherpa_onnx", | ||
| 41 | + "srcPath": "./sherpa_onnx", | ||
| 42 | + } | ||
| 43 | + ] | ||
| 44 | +} |
harmony-os/SherpaOnnxHar/code-linter.json5
0 → 100644
| 1 | +{ | ||
| 2 | + "files": [ | ||
| 3 | + "**/*.ets" | ||
| 4 | + ], | ||
| 5 | + "ignore": [ | ||
| 6 | + "**/src/ohosTest/**/*", | ||
| 7 | + "**/src/test/**/*", | ||
| 8 | + "**/src/mock/**/*", | ||
| 9 | + "**/node_modules/**/*", | ||
| 10 | + "**/oh_modules/**/*", | ||
| 11 | + "**/build/**/*", | ||
| 12 | + "**/.preview/**/*" | ||
| 13 | + ], | ||
| 14 | + "ruleSet": [ | ||
| 15 | + "plugin:@performance/recommended", | ||
| 16 | + "plugin:@typescript-eslint/recommended" | ||
| 17 | + ], | ||
| 18 | + "rules": { | ||
| 19 | + } | ||
| 20 | +} |
harmony-os/SherpaOnnxHar/entry/.gitignore
0 → 100644
| 1 | +{ | ||
| 2 | + "apiType": "stageMode", | ||
| 3 | + "buildOption": { | ||
| 4 | + }, | ||
| 5 | + "buildOptionSet": [ | ||
| 6 | + { | ||
| 7 | + "name": "release", | ||
| 8 | + "arkOptions": { | ||
| 9 | + "obfuscation": { | ||
| 10 | + "ruleOptions": { | ||
| 11 | + "enable": false, | ||
| 12 | + "files": [ | ||
| 13 | + "./obfuscation-rules.txt" | ||
| 14 | + ] | ||
| 15 | + } | ||
| 16 | + } | ||
| 17 | + } | ||
| 18 | + }, | ||
| 19 | + ], | ||
| 20 | + "targets": [ | ||
| 21 | + { | ||
| 22 | + "name": "default" | ||
| 23 | + }, | ||
| 24 | + { | ||
| 25 | + "name": "ohosTest", | ||
| 26 | + } | ||
| 27 | + ] | ||
| 28 | +} |
harmony-os/SherpaOnnxHar/entry/hvigorfile.ts
0 → 100644
| 1 | +# Define project specific obfuscation rules here. | ||
| 2 | +# You can include the obfuscation configuration files in the current module's build-profile.json5. | ||
| 3 | +# | ||
| 4 | +# For more details, see | ||
| 5 | +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 | ||
| 6 | + | ||
| 7 | +# Obfuscation options: | ||
| 8 | +# -disable-obfuscation: disable all obfuscations | ||
| 9 | +# -enable-property-obfuscation: obfuscate the property names | ||
| 10 | +# -enable-toplevel-obfuscation: obfuscate the names in the global scope | ||
| 11 | +# -compact: remove unnecessary blank spaces and all line feeds | ||
| 12 | +# -remove-log: remove all console.* statements | ||
| 13 | +# -print-namecache: print the name cache that contains the mapping from the old names to new names | ||
| 14 | +# -apply-namecache: reuse the given cache file | ||
| 15 | + | ||
| 16 | +# Keep options: | ||
| 17 | +# -keep-property-name: specifies property names that you want to keep | ||
| 18 | +# -keep-global-name: specifies names that you want to keep in the global scope | ||
| 19 | + | ||
| 20 | +-enable-property-obfuscation | ||
| 21 | +-enable-toplevel-obfuscation | ||
| 22 | +-enable-filename-obfuscation | ||
| 23 | +-enable-export-obfuscation |
| 1 | +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; | ||
| 2 | +import hilog from '@ohos.hilog'; | ||
| 3 | +import UIAbility from '@ohos.app.ability.UIAbility'; | ||
| 4 | +import Want from '@ohos.app.ability.Want'; | ||
| 5 | +import window from '@ohos.window'; | ||
| 6 | + | ||
| 7 | +export default class EntryAbility extends UIAbility { | ||
| 8 | + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { | ||
| 9 | + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); | ||
| 10 | + } | ||
| 11 | + | ||
| 12 | + onDestroy(): void { | ||
| 13 | + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + onWindowStageCreate(windowStage: window.WindowStage): void { | ||
| 17 | + // Main window is created, set main page for this ability | ||
| 18 | + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); | ||
| 19 | + | ||
| 20 | + windowStage.loadContent('pages/Index', (err) => { | ||
| 21 | + if (err.code) { | ||
| 22 | + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); | ||
| 23 | + return; | ||
| 24 | + } | ||
| 25 | + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); | ||
| 26 | + }); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + onWindowStageDestroy(): void { | ||
| 30 | + // Main window is destroyed, release UI related resources | ||
| 31 | + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + onForeground(): void { | ||
| 35 | + // Ability has brought to foreground | ||
| 36 | + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + onBackground(): void { | ||
| 40 | + // Ability has back to background | ||
| 41 | + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); | ||
| 42 | + } | ||
| 43 | +} |
| 1 | +import hilog from '@ohos.hilog'; | ||
| 2 | +import BackupExtensionAbility, { BundleVersion } from '@ohos.application.BackupExtensionAbility'; | ||
| 3 | + | ||
| 4 | +export default class EntryBackupAbility extends BackupExtensionAbility { | ||
| 5 | + async onBackup() { | ||
| 6 | + hilog.info(0x0000, 'testTag', 'onBackup ok'); | ||
| 7 | + } | ||
| 8 | + | ||
| 9 | + async onRestore(bundleVersion: BundleVersion) { | ||
| 10 | + hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); | ||
| 11 | + } | ||
| 12 | +} |
| 1 | +{ | ||
| 2 | + "module": { | ||
| 3 | + "name": "entry", | ||
| 4 | + "type": "entry", | ||
| 5 | + "description": "$string:module_desc", | ||
| 6 | + "mainElement": "EntryAbility", | ||
| 7 | + "deviceTypes": [ | ||
| 8 | + "phone", | ||
| 9 | + "tablet", | ||
| 10 | + "2in1" | ||
| 11 | + ], | ||
| 12 | + "deliveryWithInstall": true, | ||
| 13 | + "installationFree": false, | ||
| 14 | + "pages": "$profile:main_pages", | ||
| 15 | + "abilities": [ | ||
| 16 | + { | ||
| 17 | + "name": "EntryAbility", | ||
| 18 | + "srcEntry": "./ets/entryability/EntryAbility.ets", | ||
| 19 | + "description": "$string:EntryAbility_desc", | ||
| 20 | + "icon": "$media:layered_image", | ||
| 21 | + "label": "$string:EntryAbility_label", | ||
| 22 | + "startWindowIcon": "$media:startIcon", | ||
| 23 | + "startWindowBackground": "$color:start_window_background", | ||
| 24 | + "exported": true, | ||
| 25 | + "skills": [ | ||
| 26 | + { | ||
| 27 | + "entities": [ | ||
| 28 | + "entity.system.home" | ||
| 29 | + ], | ||
| 30 | + "actions": [ | ||
| 31 | + "action.system.home" | ||
| 32 | + ] | ||
| 33 | + } | ||
| 34 | + ] | ||
| 35 | + } | ||
| 36 | + ], | ||
| 37 | + "extensionAbilities": [ | ||
| 38 | + { | ||
| 39 | + "name": "EntryBackupAbility", | ||
| 40 | + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", | ||
| 41 | + "type": "backup", | ||
| 42 | + "exported": false, | ||
| 43 | + "metadata": [ | ||
| 44 | + { | ||
| 45 | + "name": "ohos.extension.backup", | ||
| 46 | + "resource": "$profile:backup_config" | ||
| 47 | + } | ||
| 48 | + ], | ||
| 49 | + } | ||
| 50 | + ] | ||
| 51 | + } | ||
| 52 | +} |
56.0 KB
12.1 KB
19.6 KB
| 1 | +import hilog from '@ohos.hilog'; | ||
| 2 | +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; | ||
| 3 | + | ||
| 4 | +export default function abilityTest() { | ||
| 5 | + describe('ActsAbilityTest', () => { | ||
| 6 | + // Defines a test suite. Two parameters are supported: test suite name and test suite function. | ||
| 7 | + beforeAll(() => { | ||
| 8 | + // Presets an action, which is performed only once before all test cases of the test suite start. | ||
| 9 | + // This API supports only one parameter: preset action function. | ||
| 10 | + }) | ||
| 11 | + beforeEach(() => { | ||
| 12 | + // Presets an action, which is performed before each unit test case starts. | ||
| 13 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 14 | + // This API supports only one parameter: preset action function. | ||
| 15 | + }) | ||
| 16 | + afterEach(() => { | ||
| 17 | + // Presets a clear action, which is performed after each unit test case ends. | ||
| 18 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 19 | + // This API supports only one parameter: clear action function. | ||
| 20 | + }) | ||
| 21 | + afterAll(() => { | ||
| 22 | + // Presets a clear action, which is performed after all test cases of the test suite end. | ||
| 23 | + // This API supports only one parameter: clear action function. | ||
| 24 | + }) | ||
| 25 | + it('assertContain', 0, () => { | ||
| 26 | + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. | ||
| 27 | + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); | ||
| 28 | + let a = 'abc'; | ||
| 29 | + let b = 'b'; | ||
| 30 | + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. | ||
| 31 | + expect(a).assertContain(b); | ||
| 32 | + expect(a).assertEqual(a); | ||
| 33 | + }) | ||
| 34 | + }) | ||
| 35 | +} |
| 1 | +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; | ||
| 2 | + | ||
| 3 | +export default function localUnitTest() { | ||
| 4 | + describe('localUnitTest', () => { | ||
| 5 | + // Defines a test suite. Two parameters are supported: test suite name and test suite function. | ||
| 6 | + beforeAll(() => { | ||
| 7 | + // Presets an action, which is performed only once before all test cases of the test suite start. | ||
| 8 | + // This API supports only one parameter: preset action function. | ||
| 9 | + }); | ||
| 10 | + beforeEach(() => { | ||
| 11 | + // Presets an action, which is performed before each unit test case starts. | ||
| 12 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 13 | + // This API supports only one parameter: preset action function. | ||
| 14 | + }); | ||
| 15 | + afterEach(() => { | ||
| 16 | + // Presets a clear action, which is performed after each unit test case ends. | ||
| 17 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 18 | + // This API supports only one parameter: clear action function. | ||
| 19 | + }); | ||
| 20 | + afterAll(() => { | ||
| 21 | + // Presets a clear action, which is performed after all test cases of the test suite end. | ||
| 22 | + // This API supports only one parameter: clear action function. | ||
| 23 | + }); | ||
| 24 | + it('assertContain', 0, () => { | ||
| 25 | + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. | ||
| 26 | + let a = 'abc'; | ||
| 27 | + let b = 'b'; | ||
| 28 | + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. | ||
| 29 | + expect(a).assertContain(b); | ||
| 30 | + expect(a).assertEqual(a); | ||
| 31 | + }); | ||
| 32 | + }); | ||
| 33 | +} |
| 1 | +{ | ||
| 2 | + "modelVersion": "5.0.0", | ||
| 3 | + "dependencies": { | ||
| 4 | + }, | ||
| 5 | + "execution": { | ||
| 6 | + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ | ||
| 7 | + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ | ||
| 8 | + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ | ||
| 9 | + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ | ||
| 10 | + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ | ||
| 11 | + }, | ||
| 12 | + "logging": { | ||
| 13 | + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ | ||
| 14 | + }, | ||
| 15 | + "debugging": { | ||
| 16 | + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ | ||
| 17 | + }, | ||
| 18 | + "nodeOptions": { | ||
| 19 | + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ | ||
| 20 | + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ | ||
| 21 | + } | ||
| 22 | +} |
harmony-os/SherpaOnnxHar/hvigorfile.ts
0 → 100644
harmony-os/SherpaOnnxHar/notes.md
0 → 100644
| 1 | +# Notes | ||
| 2 | + | ||
| 3 | +## How to publish a package | ||
| 4 | + | ||
| 5 | +Please see | ||
| 6 | + - <https://ohpm.openharmony.cn/#/cn/help/publishrequirefile> | ||
| 7 | + - <https://ohpm.openharmony.cn/#/cn/help/createandpublish> | ||
| 8 | + - <https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-har-publish-V5> | ||
| 9 | + | ||
| 10 | +## How to sign the HAP file from commandline | ||
| 11 | + | ||
| 12 | +Please see | ||
| 13 | +<https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-command-line-building-app-V5> |
| 1 | +{ | ||
| 2 | + "meta": { | ||
| 3 | + "stableOrder": true | ||
| 4 | + }, | ||
| 5 | + "lockfileVersion": 3, | ||
| 6 | + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", | ||
| 7 | + "specifiers": { | ||
| 8 | + "@ohos/hypium@1.0.19": "@ohos/hypium@1.0.19" | ||
| 9 | + }, | ||
| 10 | + "packages": { | ||
| 11 | + "@ohos/hypium@1.0.19": { | ||
| 12 | + "name": "@ohos/hypium", | ||
| 13 | + "version": "1.0.19", | ||
| 14 | + "integrity": "sha512-cEjDgLFCm3cWZDeRXk7agBUkPqjWxUo6AQeiu0gEkb3J8ESqlduQLSIXeo3cCsm8U/asL7iKjF85ZyOuufAGSQ==", | ||
| 15 | + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.19.har", | ||
| 16 | + "registryType": "ohpm" | ||
| 17 | + } | ||
| 18 | + } | ||
| 19 | +} |
harmony-os/SherpaOnnxHar/oh-package.json5
0 → 100644
| 1 | +/** | ||
| 2 | + * Use these variables when you tailor your ArkTS code. They must be of the const type. | ||
| 3 | + */ | ||
| 4 | +export const HAR_VERSION = '1.0.0'; | ||
| 5 | +export const BUILD_MODE_NAME = 'debug'; | ||
| 6 | +export const DEBUG = true; | ||
| 7 | +export const TARGET_NAME = 'default'; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * BuildProfile Class is used only for compatibility purposes. | ||
| 11 | + */ | ||
| 12 | +export default class BuildProfile { | ||
| 13 | + static readonly HAR_VERSION = HAR_VERSION; | ||
| 14 | + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; | ||
| 15 | + static readonly DEBUG = DEBUG; | ||
| 16 | + static readonly TARGET_NAME = TARGET_NAME; | ||
| 17 | +} |
| 1 | +export { readWave, readWaveFromBinary } from "libsherpa_onnx.so"; | ||
| 2 | + | ||
| 3 | +export { | ||
| 4 | + CircularBuffer, | ||
| 5 | + SileroVadConfig, | ||
| 6 | + SpeechSegment, | ||
| 7 | + Vad, | ||
| 8 | + VadConfig, | ||
| 9 | +} from './src/main/ets/components/Vad'; | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +export { | ||
| 13 | + Samples, | ||
| 14 | + OfflineStream, | ||
| 15 | + FeatureConfig, | ||
| 16 | + OfflineTransducerModelConfig, | ||
| 17 | + OfflineParaformerModelConfig, | ||
| 18 | + OfflineNemoEncDecCtcModelConfig, | ||
| 19 | + OfflineWhisperModelConfig, | ||
| 20 | + OfflineTdnnModelConfig, | ||
| 21 | + OfflineSenseVoiceModelConfig, | ||
| 22 | + OfflineMoonshineModelConfig, | ||
| 23 | + OfflineModelConfig, | ||
| 24 | + OfflineLMConfig, | ||
| 25 | + OfflineRecognizerConfig, | ||
| 26 | + OfflineRecognizerResult, | ||
| 27 | + OfflineRecognizer, | ||
| 28 | +} from './src/main/ets/components/NonStreamingAsr'; | ||
| 29 | + | ||
| 30 | +export { | ||
| 31 | + OnlineStream, | ||
| 32 | + OnlineTransducerModelConfig, | ||
| 33 | + OnlineParaformerModelConfig, | ||
| 34 | + OnlineZipformer2CtcModelConfig, | ||
| 35 | + OnlineModelConfig, | ||
| 36 | + OnlineCtcFstDecoderConfig, | ||
| 37 | + OnlineRecognizerConfig, | ||
| 38 | + OnlineRecognizerResult, | ||
| 39 | + OnlineRecognizer, | ||
| 40 | +} from './src/main/ets/components/StreamingAsr'; |
| 1 | +# Introduction | ||
| 2 | + | ||
| 3 | +[sherpa-onnx](https://github.com/k2-fsa/sherpa-onnx) is one of the deployment | ||
| 4 | +frameworks of [Next-gen Kaldi](https://github.com/k2-fsa). | ||
| 5 | + | ||
| 6 | +It supports speech-to-text, text-to-speech, speaker diarization, and VAD using | ||
| 7 | +onnxruntime without Internet connection. | ||
| 8 | + | ||
| 9 | +It also supports embedded systems, Android, iOS, HarmonyOS, | ||
| 10 | +Raspberry Pi, RISC-V, x86_64 servers, websocket server/client, | ||
| 11 | +C/C++, Python, Kotlin, C#, Go, NodeJS, Java, Swift, Dart, JavaScript, | ||
| 12 | +Flutter, Object Pascal, Lazarus, Rust, etc. |
| 1 | +{ | ||
| 2 | + "apiType": "stageMode", | ||
| 3 | + "buildOption": { | ||
| 4 | + "externalNativeOptions": { | ||
| 5 | + "path": "./src/main/cpp/CMakeLists.txt", | ||
| 6 | + "arguments": "", | ||
| 7 | + "cppFlags": "", | ||
| 8 | + "abiFilters": [ | ||
| 9 | + "arm64-v8a", | ||
| 10 | + "x86_64", | ||
| 11 | + ], | ||
| 12 | + }, | ||
| 13 | + }, | ||
| 14 | + "buildOptionSet": [ | ||
| 15 | + { | ||
| 16 | + "name": "release", | ||
| 17 | + "arkOptions": { | ||
| 18 | + "obfuscation": { | ||
| 19 | + "ruleOptions": { | ||
| 20 | + "enable": false, | ||
| 21 | + "files": [ | ||
| 22 | + "./obfuscation-rules.txt" | ||
| 23 | + ] | ||
| 24 | + }, | ||
| 25 | + "consumerFiles": [ | ||
| 26 | + "./consumer-rules.txt" | ||
| 27 | + ] | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + "nativeLib": { | ||
| 31 | + "debugSymbol": { | ||
| 32 | + "strip": true, | ||
| 33 | + "exclude": [] | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + }, | ||
| 37 | + ], | ||
| 38 | + "targets": [ | ||
| 39 | + { | ||
| 40 | + "name": "default" | ||
| 41 | + }, | ||
| 42 | + { | ||
| 43 | + "name": "ohosTest" | ||
| 44 | + } | ||
| 45 | + ] | ||
| 46 | +} |
| 1 | +# Define project specific obfuscation rules here. | ||
| 2 | +# You can include the obfuscation configuration files in the current module's build-profile.json5. | ||
| 3 | +# | ||
| 4 | +# For more details, see | ||
| 5 | +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 | ||
| 6 | + | ||
| 7 | +# Obfuscation options: | ||
| 8 | +# -disable-obfuscation: disable all obfuscations | ||
| 9 | +# -enable-property-obfuscation: obfuscate the property names | ||
| 10 | +# -enable-toplevel-obfuscation: obfuscate the names in the global scope | ||
| 11 | +# -compact: remove unnecessary blank spaces and all line feeds | ||
| 12 | +# -remove-log: remove all console.* statements | ||
| 13 | +# -print-namecache: print the name cache that contains the mapping from the old names to new names | ||
| 14 | +# -apply-namecache: reuse the given cache file | ||
| 15 | + | ||
| 16 | +# Keep options: | ||
| 17 | +# -keep-property-name: specifies property names that you want to keep | ||
| 18 | +# -keep-global-name: specifies names that you want to keep in the global scope | ||
| 19 | + | ||
| 20 | +-enable-property-obfuscation | ||
| 21 | +-enable-toplevel-obfuscation | ||
| 22 | +-enable-filename-obfuscation | ||
| 23 | +-enable-export-obfuscation |
| 1 | +{ | ||
| 2 | + "meta": { | ||
| 3 | + "stableOrder": true | ||
| 4 | + }, | ||
| 5 | + "lockfileVersion": 3, | ||
| 6 | + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", | ||
| 7 | + "specifiers": { | ||
| 8 | + "libsherpa_onnx.so@src/main/cpp/types/libsherpa_onnx": "libsherpa_onnx.so@src/main/cpp/types/libsherpa_onnx" | ||
| 9 | + }, | ||
| 10 | + "packages": { | ||
| 11 | + "libsherpa_onnx.so@src/main/cpp/types/libsherpa_onnx": { | ||
| 12 | + "name": "libsherpa_onnx.so", | ||
| 13 | + "version": "1.0.0", | ||
| 14 | + "resolved": "src/main/cpp/types/libsherpa_onnx", | ||
| 15 | + "registryType": "local" | ||
| 16 | + } | ||
| 17 | + } | ||
| 18 | +} |
| 1 | +{ | ||
| 2 | + "name": "sherpa_onnx", | ||
| 3 | + "version": "1.0.0", | ||
| 4 | + "description": "Speech-to-text, text-to-speech, and speaker diarization using Next-gen Kaldi without internet connection", | ||
| 5 | + "main": "Index.ets", | ||
| 6 | + "author": "The next-gen Kaldi team", | ||
| 7 | + "license": "Apache-2.0", | ||
| 8 | + "homepage": "https://github.com/k2-fsa/sherpa-onnx", | ||
| 9 | + "repository": "https://github.com/k2-fsa/sherpa-onnx/tree/master/harmonyos-SherpaOnnxHar", | ||
| 10 | + "dependencies": { | ||
| 11 | + "libsherpa_onnx.so": "file:./src/main/cpp/types/libsherpa_onnx" | ||
| 12 | + }, | ||
| 13 | + "keywords": [ | ||
| 14 | + "tts", | ||
| 15 | + "asr", | ||
| 16 | + "locally", | ||
| 17 | + "diarization", | ||
| 18 | + "privacy", | ||
| 19 | + "open-source", | ||
| 20 | + "speaker", | ||
| 21 | + ], | ||
| 22 | + "bugs": { | ||
| 23 | + "url": "https://github.com/k2-fsa/sherpa-onnx/issues" | ||
| 24 | + }, | ||
| 25 | +} |
| 1 | +# the minimum version of CMake. | ||
| 2 | +cmake_minimum_required(VERSION 3.13.0) | ||
| 3 | +project(myNpmLib) | ||
| 4 | + | ||
| 5 | +# Disable warning about | ||
| 6 | +# | ||
| 7 | +# "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy CMP0135 is | ||
| 8 | +# not set. | ||
| 9 | +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") | ||
| 10 | + cmake_policy(SET CMP0135 NEW) | ||
| 11 | +endif() | ||
| 12 | + | ||
| 13 | +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| 14 | + | ||
| 15 | +if(DEFINED PACKAGE_FIND_FILE) | ||
| 16 | + include(${PACKAGE_FIND_FILE}) | ||
| 17 | +endif() | ||
| 18 | + | ||
| 19 | +include_directories(${NATIVERENDER_ROOT_PATH} | ||
| 20 | + ${NATIVERENDER_ROOT_PATH}/include) | ||
| 21 | + | ||
| 22 | +include(FetchContent) | ||
| 23 | +FetchContent_Declare(node_addon_api | ||
| 24 | + GIT_REPOSITORY "https://github.com/nodejs/node-addon-api.git" | ||
| 25 | + GIT_TAG c679f6f4c9dc6bf9fc0d99cbe5982bd24a5e2c7b | ||
| 26 | + PATCH_COMMAND git checkout . && git apply --ignore-whitespace "${CMAKE_CURRENT_LIST_DIR}/my-patch.diff" | ||
| 27 | +) | ||
| 28 | +FetchContent_MakeAvailable(node_addon_api) | ||
| 29 | +FetchContent_GetProperties(node_addon_api) | ||
| 30 | +if(NOT node_addon_api_POPULATED) | ||
| 31 | + message(STATUS "Downloading node-addon-api from") | ||
| 32 | + FetchContent_Populate(node_addon_api) | ||
| 33 | +endif() | ||
| 34 | + | ||
| 35 | +message(STATUS "node-addon-api is downloaded to ${node_addon_api_SOURCE_DIR}") | ||
| 36 | +include_directories(${node_addon_api_SOURCE_DIR}) | ||
| 37 | + | ||
| 38 | +add_library(sherpa_onnx SHARED | ||
| 39 | + audio-tagging.cc | ||
| 40 | + keyword-spotting.cc | ||
| 41 | + non-streaming-asr.cc | ||
| 42 | + non-streaming-speaker-diarization.cc | ||
| 43 | + non-streaming-tts.cc | ||
| 44 | + punctuation.cc | ||
| 45 | + sherpa-onnx-node-addon-api.cc | ||
| 46 | + speaker-identification.cc | ||
| 47 | + spoken-language-identification.cc | ||
| 48 | + streaming-asr.cc | ||
| 49 | + vad.cc | ||
| 50 | + wave-reader.cc | ||
| 51 | + wave-writer.cc | ||
| 52 | +) | ||
| 53 | + | ||
| 54 | +add_library(sherpa_onnx_c_api SHARED IMPORTED) | ||
| 55 | +set_target_properties(sherpa_onnx_c_api | ||
| 56 | + PROPERTIES | ||
| 57 | + IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libs/${OHOS_ARCH}/libsherpa-onnx-c-api.so) | ||
| 58 | + | ||
| 59 | +add_library(onnxruntime SHARED IMPORTED) | ||
| 60 | +set_target_properties(onnxruntime | ||
| 61 | + PROPERTIES | ||
| 62 | + IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libs/${OHOS_ARCH}/libonnxruntime.so) | ||
| 63 | + | ||
| 64 | + | ||
| 65 | +target_link_libraries(sherpa_onnx PUBLIC libace_napi.z.so | ||
| 66 | + libhilog_ndk.z.so # for hilog | ||
| 67 | + librawfile.z.so | ||
| 68 | + sherpa_onnx_c_api onnxruntime | ||
| 69 | +) |
| 1 | +# Node | ||
| 2 | + | ||
| 3 | +[./c-api.h](./c-api.h) is a symbolic link to | ||
| 4 | +https://github.com/k2-fsa/sherpa-onnx/blob/master/sherpa-onnx/c-api/c-api.h | ||
| 5 | + | ||
| 6 | +If you are using Windows, then you need to manually replace this file with | ||
| 7 | +https://github.com/k2-fsa/sherpa-onnx/blob/master/sherpa-onnx/c-api/c-api.h | ||
| 8 | +since Windows does not support symbolic links. |
| 1 | +../../../../../../../../../sherpa-onnx/c-api/c-api.h |
| 1 | +*.so |
| 1 | +# Introduction | ||
| 2 | + | ||
| 3 | +You need to get the following four `.so` files using | ||
| 4 | + | ||
| 5 | + - [build-ohos-arm64-v8a.sh](https://github.com/k2-fsa/sherpa-onnx/blob/master/build-ohos-arm64-v8a.sh) | ||
| 6 | + - [build-ohos-x86-64.sh](https://github.com/k2-fsa/sherpa-onnx/blob/master/build-ohos-x86-64.sh) | ||
| 7 | + | ||
| 8 | +``` | ||
| 9 | +. | ||
| 10 | +├── README.md | ||
| 11 | +├── arm64-v8a | ||
| 12 | +│ ├── libonnxruntime.so | ||
| 13 | +│ └── libsherpa-onnx-c-api.so | ||
| 14 | +└── x86_64 | ||
| 15 | + ├── libonnxruntime.so | ||
| 16 | + └── libsherpa-onnx-c-api.so | ||
| 17 | +``` |
| @@ -7,6 +7,18 @@ | @@ -7,6 +7,18 @@ | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | 9 | ||
| 10 | +#if __OHOS__ | ||
| 11 | +#include "rawfile/raw_file_manager.h" | ||
| 12 | +#include "hilog/log.h" | ||
| 13 | + | ||
| 14 | +#undef LOG_DOMAIN | ||
| 15 | +#undef LOG_TAG | ||
| 16 | + | ||
| 17 | +// https://gitee.com/openharmony/docs/blob/145a084f0b742e4325915e32f8184817927d1251/en/contribute/OpenHarmony-Log-guide.md#hilog-api-usage-specifications | ||
| 18 | +#define LOG_DOMAIN 0x6666 | ||
| 19 | +#define LOG_TAG "sherpa_onnx" | ||
| 20 | +#endif | ||
| 21 | + | ||
| 10 | #define SHERPA_ONNX_ASSIGN_ATTR_STR(c_name, js_name) \ | 22 | #define SHERPA_ONNX_ASSIGN_ATTR_STR(c_name, js_name) \ |
| 11 | do { \ | 23 | do { \ |
| 12 | if (o.Has(#js_name) && o.Get(#js_name).IsString()) { \ | 24 | if (o.Has(#js_name) && o.Get(#js_name).IsString()) { \ |
| 1 | +diff --git a/napi-inl.h b/napi-inl.h | ||
| 2 | +index e7141c0..0fd90d8 100644 | ||
| 3 | +--- a/napi-inl.h | ||
| 4 | ++++ b/napi-inl.h | ||
| 5 | +@@ -2156,7 +2156,8 @@ inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value) | ||
| 6 | + | ||
| 7 | + inline void* ArrayBuffer::Data() { | ||
| 8 | + void* data; | ||
| 9 | +- napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr); | ||
| 10 | ++ size_t byte_length; | ||
| 11 | ++ napi_status status = napi_get_arraybuffer_info(_env, _value, &data, &byte_length); | ||
| 12 | + NAPI_THROW_IF_FAILED(_env, status, nullptr); | ||
| 13 | + return data; | ||
| 14 | + } |
| @@ -191,6 +191,17 @@ static SherpaOnnxOfflineLMConfig GetOfflineLMConfig(Napi::Object obj) { | @@ -191,6 +191,17 @@ static SherpaOnnxOfflineLMConfig GetOfflineLMConfig(Napi::Object obj) { | ||
| 191 | static Napi::External<SherpaOnnxOfflineRecognizer> | 191 | static Napi::External<SherpaOnnxOfflineRecognizer> |
| 192 | CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { | 192 | CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { |
| 193 | Napi::Env env = info.Env(); | 193 | Napi::Env env = info.Env(); |
| 194 | +#if __OHOS__ | ||
| 195 | + // the last argument is the NativeResourceManager | ||
| 196 | + if (info.Length() != 2) { | ||
| 197 | + std::ostringstream os; | ||
| 198 | + os << "Expect only 2 arguments. Given: " << info.Length(); | ||
| 199 | + | ||
| 200 | + Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException(); | ||
| 201 | + | ||
| 202 | + return {}; | ||
| 203 | + } | ||
| 204 | +#else | ||
| 194 | if (info.Length() != 1) { | 205 | if (info.Length() != 1) { |
| 195 | std::ostringstream os; | 206 | std::ostringstream os; |
| 196 | os << "Expect only 1 argument. Given: " << info.Length(); | 207 | os << "Expect only 1 argument. Given: " << info.Length(); |
| @@ -199,6 +210,7 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { | @@ -199,6 +210,7 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { | ||
| 199 | 210 | ||
| 200 | return {}; | 211 | return {}; |
| 201 | } | 212 | } |
| 213 | +#endif | ||
| 202 | 214 | ||
| 203 | if (!info[0].IsObject()) { | 215 | if (!info[0].IsObject()) { |
| 204 | Napi::TypeError::New(env, "Expect an object as the argument") | 216 | Napi::TypeError::New(env, "Expect an object as the argument") |
| @@ -223,8 +235,15 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { | @@ -223,8 +235,15 @@ CreateOfflineRecognizerWrapper(const Napi::CallbackInfo &info) { | ||
| 223 | SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars); | 235 | SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars); |
| 224 | SHERPA_ONNX_ASSIGN_ATTR_FLOAT(blank_penalty, blankPenalty); | 236 | SHERPA_ONNX_ASSIGN_ATTR_FLOAT(blank_penalty, blankPenalty); |
| 225 | 237 | ||
| 238 | +#if __OHOS__ | ||
| 239 | + std::unique_ptr<NativeResourceManager, decltype(&OH_ResourceManager_ReleaseNativeResourceManager)> mgr (OH_ResourceManager_InitNativeResourceManager(env, info[1]), &OH_ResourceManager_ReleaseNativeResourceManager); | ||
| 240 | + | ||
| 241 | + const SherpaOnnxOfflineRecognizer *recognizer = | ||
| 242 | + SherpaOnnxCreateOfflineRecognizerOHOS(&c, mgr.get()); | ||
| 243 | +#else | ||
| 226 | const SherpaOnnxOfflineRecognizer *recognizer = | 244 | const SherpaOnnxOfflineRecognizer *recognizer = |
| 227 | SherpaOnnxCreateOfflineRecognizer(&c); | 245 | SherpaOnnxCreateOfflineRecognizer(&c); |
| 246 | +#endif | ||
| 228 | 247 | ||
| 229 | SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.encoder); | 248 | SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.encoder); |
| 230 | SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.decoder); | 249 | SHERPA_ONNX_DELETE_C_STR(c.model_config.transducer.decoder); |
| @@ -374,8 +393,15 @@ static void AcceptWaveformOfflineWrapper(const Napi::CallbackInfo &info) { | @@ -374,8 +393,15 @@ static void AcceptWaveformOfflineWrapper(const Napi::CallbackInfo &info) { | ||
| 374 | Napi::Float32Array samples = obj.Get("samples").As<Napi::Float32Array>(); | 393 | Napi::Float32Array samples = obj.Get("samples").As<Napi::Float32Array>(); |
| 375 | int32_t sample_rate = obj.Get("sampleRate").As<Napi::Number>().Int32Value(); | 394 | int32_t sample_rate = obj.Get("sampleRate").As<Napi::Number>().Int32Value(); |
| 376 | 395 | ||
| 396 | +#if __OHOS__ | ||
| 397 | + // Note(fangjun): For unknown reasons on HarmonyOS, we need to divide it by | ||
| 398 | + // sizeof(float) here | ||
| 399 | + SherpaOnnxAcceptWaveformOffline(stream, sample_rate, samples.Data(), | ||
| 400 | + samples.ElementLength() / sizeof(float)); | ||
| 401 | +#else | ||
| 377 | SherpaOnnxAcceptWaveformOffline(stream, sample_rate, samples.Data(), | 402 | SherpaOnnxAcceptWaveformOffline(stream, sample_rate, samples.Data(), |
| 378 | samples.ElementLength()); | 403 | samples.ElementLength()); |
| 404 | +#endif | ||
| 379 | } | 405 | } |
| 380 | 406 | ||
| 381 | static void DecodeOfflineStreamWrapper(const Napi::CallbackInfo &info) { | 407 | static void DecodeOfflineStreamWrapper(const Napi::CallbackInfo &info) { |
| @@ -147,6 +147,16 @@ static SherpaOnnxOnlineCtcFstDecoderConfig GetCtcFstDecoderConfig( | @@ -147,6 +147,16 @@ static SherpaOnnxOnlineCtcFstDecoderConfig GetCtcFstDecoderConfig( | ||
| 147 | static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( | 147 | static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( |
| 148 | const Napi::CallbackInfo &info) { | 148 | const Napi::CallbackInfo &info) { |
| 149 | Napi::Env env = info.Env(); | 149 | Napi::Env env = info.Env(); |
| 150 | +#if __OHOS__ | ||
| 151 | + if (info.Length() != 2) { | ||
| 152 | + std::ostringstream os; | ||
| 153 | + os << "Expect only 2 arguments. Given: " << info.Length(); | ||
| 154 | + | ||
| 155 | + Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException(); | ||
| 156 | + | ||
| 157 | + return {}; | ||
| 158 | + } | ||
| 159 | +#else | ||
| 150 | if (info.Length() != 1) { | 160 | if (info.Length() != 1) { |
| 151 | std::ostringstream os; | 161 | std::ostringstream os; |
| 152 | os << "Expect only 1 argument. Given: " << info.Length(); | 162 | os << "Expect only 1 argument. Given: " << info.Length(); |
| @@ -155,6 +165,7 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( | @@ -155,6 +165,7 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( | ||
| 155 | 165 | ||
| 156 | return {}; | 166 | return {}; |
| 157 | } | 167 | } |
| 168 | +#endif | ||
| 158 | 169 | ||
| 159 | if (!info[0].IsObject()) { | 170 | if (!info[0].IsObject()) { |
| 160 | Napi::TypeError::New(env, "Expect an object as the argument") | 171 | Napi::TypeError::New(env, "Expect an object as the argument") |
| @@ -199,8 +210,15 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( | @@ -199,8 +210,15 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper( | ||
| 199 | 210 | ||
| 200 | c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o); | 211 | c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o); |
| 201 | 212 | ||
| 213 | +#if __OHOS__ | ||
| 214 | + std::unique_ptr<NativeResourceManager, decltype(&OH_ResourceManager_ReleaseNativeResourceManager)> mgr (OH_ResourceManager_InitNativeResourceManager(env, info[1]), &OH_ResourceManager_ReleaseNativeResourceManager); | ||
| 215 | + | ||
| 216 | + const SherpaOnnxOnlineRecognizer *recognizer = | ||
| 217 | + SherpaOnnxCreateOnlineRecognizerOHOS(&c, mgr.get()); | ||
| 218 | +#else | ||
| 202 | const SherpaOnnxOnlineRecognizer *recognizer = | 219 | const SherpaOnnxOnlineRecognizer *recognizer = |
| 203 | SherpaOnnxCreateOnlineRecognizer(&c); | 220 | SherpaOnnxCreateOnlineRecognizer(&c); |
| 221 | +#endif | ||
| 204 | 222 | ||
| 205 | if (c.model_config.transducer.encoder) { | 223 | if (c.model_config.transducer.encoder) { |
| 206 | delete[] c.model_config.transducer.encoder; | 224 | delete[] c.model_config.transducer.encoder; |
| @@ -385,8 +403,13 @@ static void AcceptWaveformWrapper(const Napi::CallbackInfo &info) { | @@ -385,8 +403,13 @@ static void AcceptWaveformWrapper(const Napi::CallbackInfo &info) { | ||
| 385 | Napi::Float32Array samples = obj.Get("samples").As<Napi::Float32Array>(); | 403 | Napi::Float32Array samples = obj.Get("samples").As<Napi::Float32Array>(); |
| 386 | int32_t sample_rate = obj.Get("sampleRate").As<Napi::Number>().Int32Value(); | 404 | int32_t sample_rate = obj.Get("sampleRate").As<Napi::Number>().Int32Value(); |
| 387 | 405 | ||
| 406 | +#if __OHOS__ | ||
| 407 | + SherpaOnnxOnlineStreamAcceptWaveform(stream, sample_rate, samples.Data(), | ||
| 408 | + samples.ElementLength() / sizeof(float)); | ||
| 409 | +#else | ||
| 388 | SherpaOnnxOnlineStreamAcceptWaveform(stream, sample_rate, samples.Data(), | 410 | SherpaOnnxOnlineStreamAcceptWaveform(stream, sample_rate, samples.Data(), |
| 389 | samples.ElementLength()); | 411 | samples.ElementLength()); |
| 412 | +#endif | ||
| 390 | } | 413 | } |
| 391 | 414 | ||
| 392 | static Napi::Boolean IsOnlineStreamReadyWrapper( | 415 | static Napi::Boolean IsOnlineStreamReadyWrapper( |
| 1 | +export const readWave: (filename: string, enableExternalBuffer: boolean = true) => {samples: Float32Array, sampleRate: number}; | ||
| 2 | +export const readWaveFromBinary: (data: Uint8Array, enableExternalBuffer: boolean = true) => {samples: Float32Array, sampleRate: number}; | ||
| 3 | +export const createCircularBuffer: (capacity: number) => object; | ||
| 4 | +export const circularBufferPush: (handle: object, samples: Float32Array) => void; | ||
| 5 | +export const circularBufferGet: (handle: object, index: number, n: number, enableExternalBuffer: boolean = true) => Float32Array; | ||
| 6 | +export const circularBufferPop: (handle: object, n: number) => void; | ||
| 7 | +export const circularBufferSize: (handle: object) => number; | ||
| 8 | +export const circularBufferHead: (handle: object) => number; | ||
| 9 | +export const circularBufferReset: (handle: object) => void; | ||
| 10 | + | ||
| 11 | +export const createVoiceActivityDetector: (config: object, bufferSizeInSeconds: number, mgr?: object) => object; | ||
| 12 | +export const voiceActivityDetectorAcceptWaveform: (handle: object, samples: Float32Array) => void; | ||
| 13 | +export const voiceActivityDetectorIsEmpty: (handle: object) => boolean; | ||
| 14 | +export const voiceActivityDetectorIsDetected: (handle: object) => boolean; | ||
| 15 | +export const voiceActivityDetectorPop: (handle: object) => void; | ||
| 16 | +export const voiceActivityDetectorClear: (handle: object) => void; | ||
| 17 | +export const voiceActivityDetectorFront: (handle: object, enableExternalBuffer: boolean = true) => {samples: Float32Array, start: number}; | ||
| 18 | +export const voiceActivityDetectorReset: (handle: object) => void; | ||
| 19 | +export const voiceActivityDetectorFlush: (handle: object) => void; | ||
| 20 | + | ||
| 21 | +export const createOfflineRecognizer: (config: object, mgr?: object) => object; | ||
| 22 | +export const createOfflineStream: (handle: object) => object; | ||
| 23 | +export const acceptWaveformOffline: (handle: object, audio: object) => void; | ||
| 24 | +export const decodeOfflineStream: (handle: object, streamHandle: object) => void; | ||
| 25 | +export const getOfflineStreamResultAsJson: (streamHandle: object) => string; | ||
| 26 | + | ||
| 27 | +export const createOnlineRecognizer: (config: object, mgr?: object) => object; | ||
| 28 | +export const createOnlineStream: (handle: object) => object; | ||
| 29 | +export const acceptWaveformOnline: (handle: object, audio: object) => void; | ||
| 30 | +export const inputFinished: (streamHandle: object) => void; | ||
| 31 | +export const isOnlineStreamReady: (handle: object, streamHandle: object) => boolean; | ||
| 32 | +export const decodeOnlineStream: (handle: object, streamHandle: object) => void; | ||
| 33 | +export const isEndpoint: (handle: object, streamHandle: object) => boolean; | ||
| 34 | +export const reset: (handle: object, streamHandle: object) => void; | ||
| 35 | +export const getOnlineStreamResultAsJson: (handle: object, streamHandle: object) => string; |
| @@ -67,7 +67,14 @@ static void CircularBufferPushWrapper(const Napi::CallbackInfo &info) { | @@ -67,7 +67,14 @@ static void CircularBufferPushWrapper(const Napi::CallbackInfo &info) { | ||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | Napi::Float32Array data = info[1].As<Napi::Float32Array>(); | 69 | Napi::Float32Array data = info[1].As<Napi::Float32Array>(); |
| 70 | + | ||
| 71 | +#if __OHOS__ | ||
| 72 | + // Note(fangjun): Normally, we don't need to divied it by sizeof(float). | ||
| 73 | + // However, data.ElementLength() here returns number of bytes, not number of elements. | ||
| 74 | + SherpaOnnxCircularBufferPush(buf, data.Data(), data.ElementLength() / sizeof(float)); | ||
| 75 | +#else | ||
| 70 | SherpaOnnxCircularBufferPush(buf, data.Data(), data.ElementLength()); | 76 | SherpaOnnxCircularBufferPush(buf, data.Data(), data.ElementLength()); |
| 77 | +#endif | ||
| 71 | } | 78 | } |
| 72 | 79 | ||
| 73 | // see https://github.com/nodejs/node-addon-api/blob/main/doc/typed_array.md | 80 | // see https://github.com/nodejs/node-addon-api/blob/main/doc/typed_array.md |
| @@ -287,6 +294,17 @@ static SherpaOnnxSileroVadModelConfig GetSileroVadConfig( | @@ -287,6 +294,17 @@ static SherpaOnnxSileroVadModelConfig GetSileroVadConfig( | ||
| 287 | static Napi::External<SherpaOnnxVoiceActivityDetector> | 294 | static Napi::External<SherpaOnnxVoiceActivityDetector> |
| 288 | CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { | 295 | CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { |
| 289 | Napi::Env env = info.Env(); | 296 | Napi::Env env = info.Env(); |
| 297 | +#if __OHOS__ | ||
| 298 | + // the last argument is a NativeResourceManager | ||
| 299 | + if (info.Length() != 3) { | ||
| 300 | + std::ostringstream os; | ||
| 301 | + os << "Expect only 3 arguments. Given: " << info.Length(); | ||
| 302 | + | ||
| 303 | + Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException(); | ||
| 304 | + | ||
| 305 | + return {}; | ||
| 306 | + } | ||
| 307 | +#else | ||
| 290 | if (info.Length() != 2) { | 308 | if (info.Length() != 2) { |
| 291 | std::ostringstream os; | 309 | std::ostringstream os; |
| 292 | os << "Expect only 2 arguments. Given: " << info.Length(); | 310 | os << "Expect only 2 arguments. Given: " << info.Length(); |
| @@ -295,6 +313,7 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { | @@ -295,6 +313,7 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { | ||
| 295 | 313 | ||
| 296 | return {}; | 314 | return {}; |
| 297 | } | 315 | } |
| 316 | +#endif | ||
| 298 | 317 | ||
| 299 | if (!info[0].IsObject()) { | 318 | if (!info[0].IsObject()) { |
| 300 | Napi::TypeError::New(env, | 319 | Napi::TypeError::New(env, |
| @@ -333,8 +352,15 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { | @@ -333,8 +352,15 @@ CreateVoiceActivityDetectorWrapper(const Napi::CallbackInfo &info) { | ||
| 333 | 352 | ||
| 334 | float buffer_size_in_seconds = info[1].As<Napi::Number>().FloatValue(); | 353 | float buffer_size_in_seconds = info[1].As<Napi::Number>().FloatValue(); |
| 335 | 354 | ||
| 355 | +#if __OHOS__ | ||
| 356 | + std::unique_ptr<NativeResourceManager, decltype(&OH_ResourceManager_ReleaseNativeResourceManager)> mgr(OH_ResourceManager_InitNativeResourceManager(env, info[2]), &OH_ResourceManager_ReleaseNativeResourceManager); | ||
| 357 | + | ||
| 358 | + SherpaOnnxVoiceActivityDetector *vad = | ||
| 359 | + SherpaOnnxCreateVoiceActivityDetectorOHOS(&c, buffer_size_in_seconds, mgr.get()); | ||
| 360 | +#else | ||
| 336 | SherpaOnnxVoiceActivityDetector *vad = | 361 | SherpaOnnxVoiceActivityDetector *vad = |
| 337 | SherpaOnnxCreateVoiceActivityDetector(&c, buffer_size_in_seconds); | 362 | SherpaOnnxCreateVoiceActivityDetector(&c, buffer_size_in_seconds); |
| 363 | +#endif | ||
| 338 | 364 | ||
| 339 | if (c.silero_vad.model) { | 365 | if (c.silero_vad.model) { |
| 340 | delete[] c.silero_vad.model; | 366 | delete[] c.silero_vad.model; |
| @@ -383,8 +409,14 @@ static void VoiceActivityDetectorAcceptWaveformWrapper( | @@ -383,8 +409,14 @@ static void VoiceActivityDetectorAcceptWaveformWrapper( | ||
| 383 | 409 | ||
| 384 | Napi::Float32Array samples = info[1].As<Napi::Float32Array>(); | 410 | Napi::Float32Array samples = info[1].As<Napi::Float32Array>(); |
| 385 | 411 | ||
| 412 | +#if __OHOS__ | ||
| 413 | + // Note(fangjun): For unknown reasons, we need to use `/sizeof(float)` here for Huawei | ||
| 414 | + SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples.Data(), | ||
| 415 | + samples.ElementLength() / sizeof(float)); | ||
| 416 | +#else | ||
| 386 | SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples.Data(), | 417 | SherpaOnnxVoiceActivityDetectorAcceptWaveform(vad, samples.Data(), |
| 387 | samples.ElementLength()); | 418 | samples.ElementLength()); |
| 419 | +#endif | ||
| 388 | } | 420 | } |
| 389 | 421 | ||
| 390 | static Napi::Boolean VoiceActivityDetectorEmptyWrapper( | 422 | static Napi::Boolean VoiceActivityDetectorEmptyWrapper( |
| @@ -85,7 +85,87 @@ static Napi::Object ReadWaveWrapper(const Napi::CallbackInfo &info) { | @@ -85,7 +85,87 @@ static Napi::Object ReadWaveWrapper(const Napi::CallbackInfo &info) { | ||
| 85 | } | 85 | } |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | +static Napi::Object ReadWaveFromBinaryWrapper(const Napi::CallbackInfo &info) { | ||
| 89 | + Napi::Env env = info.Env(); | ||
| 90 | + if (info.Length() > 2) { | ||
| 91 | + std::ostringstream os; | ||
| 92 | + os << "Expect only 1 or 2 arguments. Given: " << info.Length(); | ||
| 93 | + | ||
| 94 | + Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException(); | ||
| 95 | + | ||
| 96 | + return {}; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + if (!info[0].IsTypedArray()) { | ||
| 100 | + Napi::TypeError::New(env, "Argument 0 should be a float32 array") | ||
| 101 | + .ThrowAsJavaScriptException(); | ||
| 102 | + | ||
| 103 | + return {}; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + Napi::Uint8Array data = info[0].As<Napi::Uint8Array>(); | ||
| 107 | + int32_t n = data.ElementLength(); | ||
| 108 | + const SherpaOnnxWave *wave = SherpaOnnxReadWaveFromBinaryData(reinterpret_cast<const char*>(data.Data()), n); | ||
| 109 | + if (!wave) { | ||
| 110 | + std::ostringstream os; | ||
| 111 | + os << "Failed to read wave"; | ||
| 112 | + Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException(); | ||
| 113 | + | ||
| 114 | + return {}; | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + bool enable_external_buffer = true; | ||
| 118 | + if (info.Length() == 2) { | ||
| 119 | + if (info[1].IsBoolean()) { | ||
| 120 | + enable_external_buffer = info[1].As<Napi::Boolean>().Value(); | ||
| 121 | + } else { | ||
| 122 | + Napi::TypeError::New(env, "Argument 1 should be a boolean") | ||
| 123 | + .ThrowAsJavaScriptException(); | ||
| 124 | + | ||
| 125 | + return {}; | ||
| 126 | + } | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + if (enable_external_buffer) { | ||
| 130 | + Napi::ArrayBuffer arrayBuffer = Napi::ArrayBuffer::New( | ||
| 131 | + env, const_cast<float *>(wave->samples), | ||
| 132 | + sizeof(float) * wave->num_samples, | ||
| 133 | + [](Napi::Env /*env*/, void * /*data*/, const SherpaOnnxWave *hint) { | ||
| 134 | + SherpaOnnxFreeWave(hint); | ||
| 135 | + }, | ||
| 136 | + wave); | ||
| 137 | + Napi::Float32Array float32Array = | ||
| 138 | + Napi::Float32Array::New(env, wave->num_samples, arrayBuffer, 0); | ||
| 139 | + | ||
| 140 | + Napi::Object obj = Napi::Object::New(env); | ||
| 141 | + obj.Set(Napi::String::New(env, "samples"), float32Array); | ||
| 142 | + obj.Set(Napi::String::New(env, "sampleRate"), wave->sample_rate); | ||
| 143 | + return obj; | ||
| 144 | + } else { | ||
| 145 | + // don't use external buffer | ||
| 146 | + Napi::ArrayBuffer arrayBuffer = | ||
| 147 | + Napi::ArrayBuffer::New(env, sizeof(float) * wave->num_samples); | ||
| 148 | + | ||
| 149 | + Napi::Float32Array float32Array = | ||
| 150 | + Napi::Float32Array::New(env, wave->num_samples, arrayBuffer, 0); | ||
| 151 | + | ||
| 152 | + std::copy(wave->samples, wave->samples + wave->num_samples, | ||
| 153 | + float32Array.Data()); | ||
| 154 | + | ||
| 155 | + Napi::Object obj = Napi::Object::New(env); | ||
| 156 | + obj.Set(Napi::String::New(env, "samples"), float32Array); | ||
| 157 | + obj.Set(Napi::String::New(env, "sampleRate"), wave->sample_rate); | ||
| 158 | + | ||
| 159 | + SherpaOnnxFreeWave(wave); | ||
| 160 | + | ||
| 161 | + return obj; | ||
| 162 | + } | ||
| 163 | +} | ||
| 164 | + | ||
| 88 | void InitWaveReader(Napi::Env env, Napi::Object exports) { | 165 | void InitWaveReader(Napi::Env env, Napi::Object exports) { |
| 89 | exports.Set(Napi::String::New(env, "readWave"), | 166 | exports.Set(Napi::String::New(env, "readWave"), |
| 90 | Napi::Function::New(env, ReadWaveWrapper)); | 167 | Napi::Function::New(env, ReadWaveWrapper)); |
| 168 | + | ||
| 169 | + exports.Set(Napi::String::New(env, "readWaveFromBinary"), | ||
| 170 | + Napi::Function::New(env, ReadWaveFromBinaryWrapper)); | ||
| 91 | } | 171 | } |
| 1 | +import hilog from '@ohos.hilog'; | ||
| 2 | +import testNapi from 'libsherpa_onnx.so'; | ||
| 3 | + | ||
| 4 | +@Component | ||
| 5 | +export struct MainPage { | ||
| 6 | + @State message: string = 'Hello World'; | ||
| 7 | + | ||
| 8 | + build() { | ||
| 9 | + Row() { | ||
| 10 | + Column() { | ||
| 11 | + Text(this.message) | ||
| 12 | + .fontSize(50) | ||
| 13 | + .fontWeight(FontWeight.Bold) | ||
| 14 | + .onClick(() => { | ||
| 15 | + }) | ||
| 16 | + } | ||
| 17 | + .width('100%') | ||
| 18 | + } | ||
| 19 | + .height('100%') | ||
| 20 | + } | ||
| 21 | +} |
| 1 | +import { | ||
| 2 | + acceptWaveformOffline, | ||
| 3 | + createOfflineRecognizer, | ||
| 4 | + createOfflineStream, | ||
| 5 | + decodeOfflineStream, | ||
| 6 | + getOfflineStreamResultAsJson, | ||
| 7 | +} from 'libsherpa_onnx.so'; | ||
| 8 | + | ||
| 9 | +export interface Samples { | ||
| 10 | + samples: Float32Array; | ||
| 11 | + sampleRate: number; | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +export class OfflineStream { | ||
| 15 | + public handle: object; | ||
| 16 | + | ||
| 17 | + constructor(handle: object) { | ||
| 18 | + this.handle = handle; | ||
| 19 | + } | ||
| 20 | + | ||
| 21 | + // obj is {samples: samples, sampleRate: sampleRate} | ||
| 22 | + // samples is a float32 array containing samples in the range [-1, 1] | ||
| 23 | + // sampleRate is a number | ||
| 24 | + acceptWaveform(obj: Samples) { | ||
| 25 | + acceptWaveformOffline(this.handle, obj) | ||
| 26 | + } | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +export class FeatureConfig { | ||
| 30 | + public sampleRate: number = 16000; | ||
| 31 | + public featureDim: number = 80; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +export class OfflineTransducerModelConfig { | ||
| 35 | + public encoder: string = ''; | ||
| 36 | + public decoder: string = ''; | ||
| 37 | + public joiner: string = ''; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +export class OfflineParaformerModelConfig { | ||
| 41 | + public model: string = ''; | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +export class OfflineNemoEncDecCtcModelConfig { | ||
| 45 | + public model: string = ''; | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +export class OfflineWhisperModelConfig { | ||
| 49 | + public encoder: string = ''; | ||
| 50 | + public decoder: string = ''; | ||
| 51 | + public language: string = ''; | ||
| 52 | + public task: string = 'transcribe'; | ||
| 53 | + public tailPaddings: number = -1; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +export class OfflineTdnnModelConfig { | ||
| 57 | + public model: string = ''; | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +export class OfflineSenseVoiceModelConfig { | ||
| 61 | + public model: string = ''; | ||
| 62 | + public language: string = ''; | ||
| 63 | + public useItn: boolean = false; | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +export class OfflineMoonshineModelConfig { | ||
| 67 | + public preprocessor: string = ''; | ||
| 68 | + public encoder: string = ''; | ||
| 69 | + public uncachedDecoder: string = ''; | ||
| 70 | + public cachedDecoder: string = ''; | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +export class OfflineModelConfig { | ||
| 74 | + public transducer: OfflineTransducerModelConfig = new OfflineTransducerModelConfig(); | ||
| 75 | + public paraformer: OfflineParaformerModelConfig = new OfflineParaformerModelConfig(); | ||
| 76 | + public nemoCtc: OfflineNemoEncDecCtcModelConfig = new OfflineNemoEncDecCtcModelConfig(); | ||
| 77 | + public whisper: OfflineWhisperModelConfig = new OfflineWhisperModelConfig(); | ||
| 78 | + public tdnn: OfflineTdnnModelConfig = new OfflineTdnnModelConfig(); | ||
| 79 | + public tokens: string = ''; | ||
| 80 | + public numThreads: number = 1; | ||
| 81 | + public debug: boolean = false; | ||
| 82 | + public provider: string = "cpu"; | ||
| 83 | + public modelType: string = ''; | ||
| 84 | + public modelingUnit: string = "cjkchar"; | ||
| 85 | + public bpeVocab: string = ''; | ||
| 86 | + public telespeechCtc: string = ''; | ||
| 87 | + public senseVoice: OfflineSenseVoiceModelConfig = new OfflineSenseVoiceModelConfig(); | ||
| 88 | + public moonshine: OfflineMoonshineModelConfig = new OfflineMoonshineModelConfig(); | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +export class OfflineLMConfig { | ||
| 92 | + public model: string = ''; | ||
| 93 | + public scale: number = 1.0; | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +export class OfflineRecognizerConfig { | ||
| 97 | + public featConfig: FeatureConfig = new FeatureConfig(); | ||
| 98 | + public modelConfig: OfflineModelConfig = new OfflineModelConfig(); | ||
| 99 | + public lmConfig: OfflineLMConfig = new OfflineLMConfig(); | ||
| 100 | + public decodingMethod: string = "greedy_search"; | ||
| 101 | + public maxActivePaths: number = 4; | ||
| 102 | + public hotwordsFfile: string = ''; | ||
| 103 | + public hotwordsScore: number = 1.5; | ||
| 104 | + public ruleFsts: string = ''; | ||
| 105 | + public ruleFars: string = ''; | ||
| 106 | + public blankPenalty: number = 0; | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +export class OfflineRecognizerResult { | ||
| 110 | + public text: string = ''; | ||
| 111 | + public timestamps: number[] = []; | ||
| 112 | + public tokens: string[] = []; | ||
| 113 | + public json = ''; | ||
| 114 | + public lang: string = ''; | ||
| 115 | + public emotion: string = ''; | ||
| 116 | + public event: string = ''; | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +interface OfflineRecognizerResultJson { | ||
| 120 | + text: string; | ||
| 121 | + timestamps: number[]; | ||
| 122 | + tokens: string[]; | ||
| 123 | + lang: string; | ||
| 124 | + emotion: string; | ||
| 125 | + event: string; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +export class OfflineRecognizer { | ||
| 129 | + public handle: object; | ||
| 130 | + public config: OfflineRecognizerConfig; | ||
| 131 | + | ||
| 132 | + constructor(config: OfflineRecognizerConfig, mgr?: object) { | ||
| 133 | + this.handle = createOfflineRecognizer(config, mgr); | ||
| 134 | + this.config = config | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + createStream(): OfflineStream { | ||
| 138 | + const handle: object = createOfflineStream(this.handle); | ||
| 139 | + return new OfflineStream(handle); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + decode(stream: OfflineStream) { | ||
| 143 | + decodeOfflineStream(this.handle, stream.handle); | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + getResult(stream: OfflineStream): OfflineRecognizerResult { | ||
| 147 | + const jsonStr: string = getOfflineStreamResultAsJson(stream.handle); | ||
| 148 | + | ||
| 149 | + let o = JSON.parse(jsonStr) as OfflineRecognizerResultJson; | ||
| 150 | + | ||
| 151 | + const r = new OfflineRecognizerResult() | ||
| 152 | + r.text = o.text | ||
| 153 | + r.timestamps = o.timestamps; | ||
| 154 | + r.tokens = o.tokens; | ||
| 155 | + r.json = jsonStr; | ||
| 156 | + r.lang = o.lang; | ||
| 157 | + r.emotion = o.emotion; | ||
| 158 | + r.event = o.event; | ||
| 159 | + | ||
| 160 | + return r; | ||
| 161 | + } | ||
| 162 | +} |
| 1 | +import { | ||
| 2 | + acceptWaveformOnline, | ||
| 3 | + createOnlineRecognizer, | ||
| 4 | + createOnlineStream, | ||
| 5 | + decodeOnlineStream, | ||
| 6 | + getOnlineStreamResultAsJson, | ||
| 7 | + inputFinished, | ||
| 8 | + isEndpoint, | ||
| 9 | + isOnlineStreamReady, | ||
| 10 | + reset, | ||
| 11 | +} from 'libsherpa_onnx.so'; | ||
| 12 | + | ||
| 13 | +import { FeatureConfig, Samples } from './NonStreamingAsr'; | ||
| 14 | + | ||
| 15 | +export class OnlineStream { | ||
| 16 | + public handle: object; | ||
| 17 | + | ||
| 18 | + constructor(handle: object) { | ||
| 19 | + this.handle = handle; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + // obj is {samples: samples, sampleRate: sampleRate} | ||
| 23 | + // samples is a float32 array containing samples in the range [-1, 1] | ||
| 24 | + // sampleRate is a number | ||
| 25 | + acceptWaveform(obj: Samples) { | ||
| 26 | + acceptWaveformOnline(this.handle, obj) | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + inputFinished() { | ||
| 30 | + inputFinished(this.handle) | ||
| 31 | + } | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +export class OnlineTransducerModelConfig { | ||
| 35 | + public encoder: string = ''; | ||
| 36 | + public decoder: string = ''; | ||
| 37 | + public joiner: string = ''; | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +export class OnlineParaformerModelConfig { | ||
| 41 | + public encoder: string = ''; | ||
| 42 | + public decoder: string = ''; | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +export class OnlineZipformer2CtcModelConfig { | ||
| 46 | + public model: string = ''; | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +export class OnlineModelConfig { | ||
| 50 | + public transducer: OnlineTransducerModelConfig = new OnlineTransducerModelConfig(); | ||
| 51 | + public paraformer: OnlineParaformerModelConfig = new OnlineParaformerModelConfig(); | ||
| 52 | + public zipformer2_ctc: OnlineZipformer2CtcModelConfig = new OnlineZipformer2CtcModelConfig(); | ||
| 53 | + public tokens: string = ''; | ||
| 54 | + public numThreads: number = 1; | ||
| 55 | + public provider: string = "cpu"; | ||
| 56 | + public debug: boolean = false; | ||
| 57 | + public modelType: string = ''; | ||
| 58 | + public modelingUnit: string = "cjkchar"; | ||
| 59 | + public bpeVocab: string = ''; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +export class OnlineCtcFstDecoderConfig { | ||
| 63 | + public graph: string = ''; | ||
| 64 | + public maxActive: number = 3000; | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +export class OnlineRecognizerConfig { | ||
| 68 | + public featConfig: FeatureConfig = new FeatureConfig(); | ||
| 69 | + public modelConfig: OnlineModelConfig = new OnlineModelConfig(); | ||
| 70 | + public decodingMethod: string = "greedy_search"; | ||
| 71 | + public maxActivePaths: number = 4; | ||
| 72 | + public enableEndpoint: boolean = false; | ||
| 73 | + public rule1MinTrailingSilence: number = 2.4; | ||
| 74 | + public rule2MinTrailingSilence: number = 1.2; | ||
| 75 | + public rule3MinUtteranceLength: number = 20; | ||
| 76 | + public hotwordsFile: string = ''; | ||
| 77 | + public hotwordsScore: number = 1.5; | ||
| 78 | + public ctcFstDecoderConfig: OnlineCtcFstDecoderConfig = new OnlineCtcFstDecoderConfig(); | ||
| 79 | + public ruleFsts: string = ''; | ||
| 80 | + public ruleFars: string = ''; | ||
| 81 | + public blankPenalty: number = 0; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +interface OnlineRecognizerResultJson { | ||
| 85 | + text: string; | ||
| 86 | + timestamps: number[]; | ||
| 87 | + tokens: string[]; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +export class OnlineRecognizerResult { | ||
| 91 | + public text: string = ''; | ||
| 92 | + public tokens: string[] = []; | ||
| 93 | + public timestamps: number[] = []; | ||
| 94 | + public json: string = ''; | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +export class OnlineRecognizer { | ||
| 98 | + public handle: object; | ||
| 99 | + public config: OnlineRecognizerConfig | ||
| 100 | + | ||
| 101 | + constructor(config: OnlineRecognizerConfig, mgr?: object) { | ||
| 102 | + this.handle = createOnlineRecognizer(config, mgr); | ||
| 103 | + this.config = config | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + createStream(): OnlineStream { | ||
| 107 | + const handle: object = createOnlineStream(this.handle); | ||
| 108 | + return new OnlineStream(handle); | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + isReady(stream: OnlineStream): boolean { | ||
| 112 | + return isOnlineStreamReady(this.handle, stream.handle); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + decode(stream: OnlineStream) { | ||
| 116 | + decodeOnlineStream(this.handle, stream.handle); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + isEndpoint(stream: OnlineStream): boolean { | ||
| 120 | + return isEndpoint(this.handle, stream.handle); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + reset(stream: OnlineStream) { | ||
| 124 | + reset(this.handle, stream.handle); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + getResult(stream: OnlineStream): OnlineRecognizerResult { | ||
| 128 | + const jsonStr: string = | ||
| 129 | + getOnlineStreamResultAsJson(this.handle, stream.handle); | ||
| 130 | + | ||
| 131 | + let o = JSON.parse(jsonStr) as OnlineRecognizerResultJson; | ||
| 132 | + | ||
| 133 | + const r = new OnlineRecognizerResult() | ||
| 134 | + r.text = o.text | ||
| 135 | + r.timestamps = o.timestamps; | ||
| 136 | + r.tokens = o.tokens; | ||
| 137 | + r.json = jsonStr; | ||
| 138 | + | ||
| 139 | + return r; | ||
| 140 | + } | ||
| 141 | +} |
| 1 | +import { | ||
| 2 | + circularBufferGet, | ||
| 3 | + circularBufferHead, | ||
| 4 | + circularBufferPop, | ||
| 5 | + circularBufferPush, | ||
| 6 | + circularBufferReset, | ||
| 7 | + circularBufferSize, | ||
| 8 | + createCircularBuffer, | ||
| 9 | + createVoiceActivityDetector, | ||
| 10 | + voiceActivityDetectorAcceptWaveform, | ||
| 11 | + voiceActivityDetectorClear, | ||
| 12 | + voiceActivityDetectorFlush, | ||
| 13 | + voiceActivityDetectorFront, | ||
| 14 | + voiceActivityDetectorIsDetected, | ||
| 15 | + voiceActivityDetectorIsEmpty, | ||
| 16 | + voiceActivityDetectorPop, | ||
| 17 | + voiceActivityDetectorReset, | ||
| 18 | +} from 'libsherpa_onnx.so'; | ||
| 19 | + | ||
| 20 | +export class SileroVadConfig { | ||
| 21 | + public model: string; | ||
| 22 | + public threshold: number; | ||
| 23 | + public minSpeechDuration: number; | ||
| 24 | + public minSilenceDuration: number; | ||
| 25 | + public windowSize: number; | ||
| 26 | + | ||
| 27 | + public constructor(model: string, threshold: number, minSpeechDuration: number, minSilenceDuration: number, | ||
| 28 | + windowSize: number) { | ||
| 29 | + this.model = model; | ||
| 30 | + this.threshold = threshold; | ||
| 31 | + this.minSpeechDuration = minSpeechDuration; | ||
| 32 | + this.minSilenceDuration = minSilenceDuration; | ||
| 33 | + this.windowSize = windowSize; | ||
| 34 | + } | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +export class VadConfig { | ||
| 38 | + public sileroVad: SileroVadConfig; | ||
| 39 | + public sampleRate: number; | ||
| 40 | + public debug: boolean; | ||
| 41 | + public numThreads: number; | ||
| 42 | + | ||
| 43 | + public constructor(sileroVad: SileroVadConfig, sampleRate: number, debug: boolean, numThreads: number) { | ||
| 44 | + this.sileroVad = sileroVad; | ||
| 45 | + this.sampleRate = sampleRate; | ||
| 46 | + this.debug = debug; | ||
| 47 | + this.numThreads = numThreads; | ||
| 48 | + } | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +export class CircularBuffer { | ||
| 52 | + private handle: object; | ||
| 53 | + | ||
| 54 | + constructor(capacity: number) { | ||
| 55 | + this.handle = createCircularBuffer(capacity); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + // samples is a float32 array | ||
| 59 | + push(samples: Float32Array) { | ||
| 60 | + console.log(`here samples: ${samples}`); | ||
| 61 | + circularBufferPush(this.handle, samples); | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + // return a float32 array | ||
| 65 | + get(startIndex: number, n: number, enableExternalBuffer: boolean = true): Float32Array { | ||
| 66 | + return circularBufferGet( | ||
| 67 | + this.handle, startIndex, n, enableExternalBuffer); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + pop(n: number) { | ||
| 71 | + circularBufferPop(this.handle, n); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + size(): number { | ||
| 75 | + return circularBufferSize(this.handle); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + head(): number { | ||
| 79 | + return circularBufferHead(this.handle); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + reset() { | ||
| 83 | + circularBufferReset(this.handle); | ||
| 84 | + } | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +export interface SpeechSegment { | ||
| 88 | + samples: Float32Array; | ||
| 89 | + start: number; | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +export class Vad { | ||
| 93 | + public config: VadConfig; | ||
| 94 | + private handle: object; | ||
| 95 | + | ||
| 96 | + constructor(config: VadConfig, bufferSizeInSeconds?: number, mgr?: object) { | ||
| 97 | + this.handle = | ||
| 98 | + createVoiceActivityDetector(config, bufferSizeInSeconds, mgr); | ||
| 99 | + this.config = config; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + acceptWaveform(samples: Float32Array): void { | ||
| 103 | + voiceActivityDetectorAcceptWaveform(this.handle, samples); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + isEmpty(): boolean { | ||
| 107 | + return voiceActivityDetectorIsEmpty(this.handle); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + isDetected(): boolean { | ||
| 111 | + return voiceActivityDetectorIsDetected(this.handle); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + pop(): void { | ||
| 115 | + voiceActivityDetectorPop(this.handle); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + clear(): void { | ||
| 119 | + voiceActivityDetectorClear(this.handle); | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + front(enableExternalBuffer = true): SpeechSegment { | ||
| 123 | + return voiceActivityDetectorFront(this.handle, enableExternalBuffer); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + reset(): void { | ||
| 127 | + voiceActivityDetectorReset(this.handle); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + flush(): void { | ||
| 131 | + voiceActivityDetectorFlush(this.handle); | ||
| 132 | + } | ||
| 133 | +} |
| 1 | +import hilog from '@ohos.hilog'; | ||
| 2 | +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; | ||
| 3 | + | ||
| 4 | +export default function abilityTest() { | ||
| 5 | + describe('ActsAbilityTest', () => { | ||
| 6 | + // Defines a test suite. Two parameters are supported: test suite name and test suite function. | ||
| 7 | + beforeAll(() => { | ||
| 8 | + // Presets an action, which is performed only once before all test cases of the test suite start. | ||
| 9 | + // This API supports only one parameter: preset action function. | ||
| 10 | + }) | ||
| 11 | + beforeEach(() => { | ||
| 12 | + // Presets an action, which is performed before each unit test case starts. | ||
| 13 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 14 | + // This API supports only one parameter: preset action function. | ||
| 15 | + }) | ||
| 16 | + afterEach(() => { | ||
| 17 | + // Presets a clear action, which is performed after each unit test case ends. | ||
| 18 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 19 | + // This API supports only one parameter: clear action function. | ||
| 20 | + }) | ||
| 21 | + afterAll(() => { | ||
| 22 | + // Presets a clear action, which is performed after all test cases of the test suite end. | ||
| 23 | + // This API supports only one parameter: clear action function. | ||
| 24 | + }) | ||
| 25 | + it('assertContain', 0, () => { | ||
| 26 | + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. | ||
| 27 | + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); | ||
| 28 | + let a = 'abc'; | ||
| 29 | + let b = 'b'; | ||
| 30 | + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. | ||
| 31 | + expect(a).assertContain(b); | ||
| 32 | + expect(a).assertEqual(a); | ||
| 33 | + }) | ||
| 34 | + }) | ||
| 35 | +} |
| 1 | +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; | ||
| 2 | + | ||
| 3 | +export default function localUnitTest() { | ||
| 4 | + describe('localUnitTest', () => { | ||
| 5 | + // Defines a test suite. Two parameters are supported: test suite name and test suite function. | ||
| 6 | + beforeAll(() => { | ||
| 7 | + // Presets an action, which is performed only once before all test cases of the test suite start. | ||
| 8 | + // This API supports only one parameter: preset action function. | ||
| 9 | + }); | ||
| 10 | + beforeEach(() => { | ||
| 11 | + // Presets an action, which is performed before each unit test case starts. | ||
| 12 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 13 | + // This API supports only one parameter: preset action function. | ||
| 14 | + }); | ||
| 15 | + afterEach(() => { | ||
| 16 | + // Presets a clear action, which is performed after each unit test case ends. | ||
| 17 | + // The number of execution times is the same as the number of test cases defined by **it**. | ||
| 18 | + // This API supports only one parameter: clear action function. | ||
| 19 | + }); | ||
| 20 | + afterAll(() => { | ||
| 21 | + // Presets a clear action, which is performed after all test cases of the test suite end. | ||
| 22 | + // This API supports only one parameter: clear action function. | ||
| 23 | + }); | ||
| 24 | + it('assertContain', 0, () => { | ||
| 25 | + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. | ||
| 26 | + let a = 'abc'; | ||
| 27 | + let b = 'b'; | ||
| 28 | + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. | ||
| 29 | + expect(a).assertContain(b); | ||
| 30 | + expect(a).assertEqual(a); | ||
| 31 | + }); | ||
| 32 | + }); | ||
| 33 | +} |
scripts/node-addon-api/src/audio-tagging.cc
0 → 120000
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/audio-tagging.cc |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/keyword-spotting.cc |
scripts/node-addon-api/src/macros.h
0 → 120000
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/macros.h |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/non-streaming-asr.cc |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/non-streaming-speaker-diarization.cc |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/non-streaming-tts.cc |
scripts/node-addon-api/src/punctuation.cc
0 → 120000
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/punctuation.cc |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/sherpa-onnx-node-addon-api.cc |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/speaker-identification.cc |
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/spoken-language-identification.cc |
scripts/node-addon-api/src/streaming-asr.cc
0 → 120000
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/streaming-asr.cc |
scripts/node-addon-api/src/vad.cc
0 → 120000
| 1 | +../../../harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/vad.cc |
-
请 注册 或 登录 后发表评论