From d08cc04567dd842c896a03d1d9be46f1f2eeb99b Mon Sep 17 00:00:00 2001 From: Fangjun Kuang Date: Fri, 14 Jun 2024 10:37:16 +0800 Subject: [PATCH] Add VAD example for Dart API (#996) --- .../workflows/build-wheels-macos-arm64.yaml | 12 +- .../build-wheels-macos-universal2.yaml | 2 +- .github/workflows/build-wheels-macos-x64.yaml | 12 +- .github/workflows/flutter-macos.yaml | 48 ++- .github/workflows/flutter-windows-x64.yaml | 46 +- .github/workflows/test-dart.yaml | 60 +++ CMakeLists.txt | 5 +- cmake/cmake_extension.py | 8 +- cmake/kaldi-decoder.cmake | 16 +- cmake/kaldifst.cmake | 17 +- cmake/openfst.cmake | 20 +- dart-api-examples/README.md | 18 + dart-api-examples/vad/.gitignore | 3 + dart-api-examples/vad/CHANGELOG.md | 3 + dart-api-examples/vad/README.md | 21 + dart-api-examples/vad/analysis_options.yaml | 30 ++ dart-api-examples/vad/bin/vad.dart | 93 ++++ dart-api-examples/vad/pubspec.lock | 402 ++++++++++++++++++ dart-api-examples/vad/pubspec.yaml | 17 + dart-api-examples/vad/run.sh | 22 + scripts/dotnet/generate.py | 6 +- scripts/dotnet/run.sh | 2 +- sherpa-onnx/flutter/CHANGELOG.md | 11 + sherpa-onnx/flutter/lib/sherpa_onnx.dart | 24 +- .../flutter/lib/src/offline_recognizer.dart | 3 +- .../flutter/lib/src/offline_stream.dart | 2 +- .../flutter/lib/src/online_recognizer.dart | 3 +- .../flutter/lib/src/online_stream.dart | 3 +- .../flutter/lib/src/sherpa_onnx_bindings.dart | 7 +- sherpa-onnx/flutter/lib/src/vad.dart | 20 +- sherpa-onnx/flutter/notes.md | 17 + sherpa-onnx/flutter/pubspec.yaml | 66 +-- sherpa-onnx/flutter/windows/CMakeLists.txt | 6 +- 33 files changed, 883 insertions(+), 142 deletions(-) create mode 100644 .github/workflows/test-dart.yaml create mode 100644 dart-api-examples/README.md create mode 100644 dart-api-examples/vad/.gitignore create mode 100644 dart-api-examples/vad/CHANGELOG.md create mode 100644 dart-api-examples/vad/README.md create mode 100644 dart-api-examples/vad/analysis_options.yaml create mode 100644 dart-api-examples/vad/bin/vad.dart create mode 100644 dart-api-examples/vad/pubspec.lock create mode 100644 dart-api-examples/vad/pubspec.yaml create mode 100755 dart-api-examples/vad/run.sh create mode 100644 sherpa-onnx/flutter/CHANGELOG.md diff --git a/.github/workflows/build-wheels-macos-arm64.yaml b/.github/workflows/build-wheels-macos-arm64.yaml index 9a8edd504..c31d92bf4 100644 --- a/.github/workflows/build-wheels-macos-arm64.yaml +++ b/.github/workflows/build-wheels-macos-arm64.yaml @@ -48,7 +48,7 @@ jobs: path: ./wheelhouse/*.whl - name: Publish to huggingface - if: matrix.python-version == 'cp38' + if: matrix.python-version == 'cp39' env: HF_TOKEN: ${{ secrets.HF_TOKEN }} uses: nick-fields/retry@v3 @@ -82,7 +82,13 @@ jobs: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python3 -m pip install --break-system-packages --upgrade pip - python3 -m pip install --break-system-packages wheel twine setuptools + opts='--break-system-packages' + v=${{ matrix.python-version }} + if [[ $v == cp38 || $v == cp39 ]]; then + opts='' + fi + + python3 -m pip install $opts --upgrade pip + python3 -m pip install $opts wheel twine setuptools twine upload ./wheelhouse/*.whl diff --git a/.github/workflows/build-wheels-macos-universal2.yaml b/.github/workflows/build-wheels-macos-universal2.yaml index 4d52110ee..d08a93075 100644 --- a/.github/workflows/build-wheels-macos-universal2.yaml +++ b/.github/workflows/build-wheels-macos-universal2.yaml @@ -50,7 +50,7 @@ jobs: path: ./wheelhouse/*.whl - name: Publish to huggingface - if: matrix.python-version == 'cp38' + if: matrix.python-version == 'cp39' env: HF_TOKEN: ${{ secrets.HF_TOKEN }} uses: nick-fields/retry@v3 diff --git a/.github/workflows/build-wheels-macos-x64.yaml b/.github/workflows/build-wheels-macos-x64.yaml index fbd7781b5..250ef76c7 100644 --- a/.github/workflows/build-wheels-macos-x64.yaml +++ b/.github/workflows/build-wheels-macos-x64.yaml @@ -65,7 +65,7 @@ jobs: path: ./wheelhouse/*.whl - name: Publish to huggingface - if: matrix.python-version == 'cp38' + if: matrix.python-version == 'cp39' env: HF_TOKEN: ${{ secrets.HF_TOKEN }} uses: nick-fields/retry@v3 @@ -99,7 +99,13 @@ jobs: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | - python3 -m pip install --break-system-packages --upgrade pip - python3 -m pip install --break-system-packages wheel twine setuptools + opts='--break-system-packages' + v=${{ matrix.python-version }} + if [[ $v == cp38 || $v == cp39 ]]; then + opts='' + fi + + python3 -m pip install $opts --upgrade pip + python3 -m pip install $opts wheel twine setuptools twine upload ./wheelhouse/*.whl diff --git a/.github/workflows/flutter-macos.yaml b/.github/workflows/flutter-macos.yaml index 3ffa700f7..25a53d89a 100644 --- a/.github/workflows/flutter-macos.yaml +++ b/.github/workflows/flutter-macos.yaml @@ -152,6 +152,8 @@ jobs: - name: Build flutter shell: bash run: | + SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2) + d=$PWD pushd sherpa-onnx/flutter @@ -166,7 +168,7 @@ jobs: tree ./sherpa_onnx.app - app=flutter_sherpa_onnx_macos_${{ matrix.arch }}.app + app=sherpa-onnx-osx-${{ matrix.arch }}-$SHERPA_ONNX_VERSION.app mv sherpa_onnx.app $app tar cjfv $app.tar.bz2 $app ls -lh @@ -178,13 +180,43 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: flutter-sherpa-onnx-app-macos-${{ matrix.arch }} + name: sherpa-onnx-osx-${{ matrix.arch }} path: ./*.tar.bz2 - - name: Release android libs - if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 + - name: Publish to huggingface + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + uses: nick-fields/retry@v3 with: - file_glob: true - overwrite: true - file: flutter*.tar.bz2 + max_attempts: 20 + timeout_seconds: 200 + shell: bash + command: | + git config --global user.email "csukuangfj@gmail.com" + git config --global user.name "Fangjun Kuang" + + rm -rf huggingface + export GIT_LFS_SKIP_SMUDGE=1 + export GIT_CLONE_PROTECTION_ACTIVE=false + + git clone https://huggingface.co/csukuangfj/sherpa-onnx-flutter huggingface + cd huggingface + git fetch + git pull + git merge -m "merge remote" --ff origin main + mkdir -p flutter + cp -v ../*.tar.bz2 ./flutter + + git status + git lfs track "*.bz2" + git add . + git commit -m "add more files" + git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-flutter main + + # - name: Release android libs + # if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') + # uses: svenstaro/upload-release-action@v2 + # with: + # file_glob: true + # overwrite: true + # file: sherpa*.tar.bz2 diff --git a/.github/workflows/flutter-windows-x64.yaml b/.github/workflows/flutter-windows-x64.yaml index f09187ca7..cfe54b053 100644 --- a/.github/workflows/flutter-windows-x64.yaml +++ b/.github/workflows/flutter-windows-x64.yaml @@ -142,7 +142,7 @@ jobs: cd build/windows/x64/runner/ - dst=flutter_sherpa_onnx_windows_x64 + dst=sherpa-onnx-win-x64-$SHERPA_ONNX_VERSION mv Release $dst tar cjfv $dst.tar.bz2 ./$dst @@ -155,13 +155,43 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: flutter-sherpa-onnx-windows-x64 + name: sherpa-onnx-win-x64 path: ./*.tar.bz2 - - name: Release android libs - if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') - uses: svenstaro/upload-release-action@v2 + - name: Publish to huggingface + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + uses: nick-fields/retry@v3 with: - file_glob: true - overwrite: true - file: flutter*.tar.bz2 + max_attempts: 20 + timeout_seconds: 200 + shell: bash + command: | + git config --global user.email "csukuangfj@gmail.com" + git config --global user.name "Fangjun Kuang" + + rm -rf huggingface + export GIT_LFS_SKIP_SMUDGE=1 + export GIT_CLONE_PROTECTION_ACTIVE=false + + git clone https://huggingface.co/csukuangfj/sherpa-onnx-flutter huggingface + cd huggingface + git fetch + git pull + git merge -m "merge remote" --ff origin main + mkdir -p flutter + cp -v ../*.tar.bz2 ./flutter + + git status + git lfs track "*.bz2" + git add . + git commit -m "add more files" + git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/sherpa-onnx-flutter main + + # - name: Release android libs + # if: (github.repository_owner == 'csukuangfj' || github.repository_owner == 'k2-fsa') && github.event_name == 'push' && contains(github.ref, 'refs/tags/') + # uses: svenstaro/upload-release-action@v2 + # with: + # file_glob: true + # overwrite: true + # file: sherpa*.tar.bz2 diff --git a/.github/workflows/test-dart.yaml b/.github/workflows/test-dart.yaml new file mode 100644 index 000000000..0734df705 --- /dev/null +++ b/.github/workflows/test-dart.yaml @@ -0,0 +1,60 @@ +name: test-dart + +on: + push: + branches: + - master + paths: + - '.github/workflows/test-dart.yaml' + - 'dart-api-examples/**' + pull_request: + branches: + - master + paths: + - '.github/workflows/test-dart.yaml' + - 'dart-api-examples/**' + + workflow_dispatch: + +concurrency: + group: test-dart-${{ github.ref }} + cancel-in-progress: true + +jobs: + dart: + name: ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest, ubuntu-latest] #, windows-latest] + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Flutter SDK + uses: flutter-actions/setup-flutter@v3 + with: + channel: stable + version: latest + + - name: Display flutter info + shell: bash + run: | + which flutter + which dart + + flutter --version + dart --version + flutter doctor + + - name: Run tests + shell: bash + run: | + cd dart-api-examples + + pushd vad + ./run.sh + popd diff --git a/CMakeLists.txt b/CMakeLists.txt index 7302a16b9..4c1f66416 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,10 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14" CACHE STRING "Minimum OS X deployment ve project(sherpa-onnx) -set(SHERPA_ONNX_VERSION "1.9.28") +# Remember to update +# ./nodejs-addon-examples +# ./dart-api-examples/ +set(SHERPA_ONNX_VERSION "1.9.29") # Disable warning about # diff --git a/cmake/cmake_extension.py b/cmake/cmake_extension.py index 46116f5c5..68be0f0c4 100644 --- a/cmake/cmake_extension.py +++ b/cmake/cmake_extension.py @@ -84,9 +84,9 @@ def get_binaries(): "piper_phonemize.dll", "sherpa-onnx-c-api.dll", "sherpa-onnx-core.dll", - "sherpa-onnx-fstfar.lib", - "sherpa-onnx-fst.lib", - "sherpa-onnx-kaldifst-core.lib", + "sherpa-onnx-fstfar.dll", + "sherpa-onnx-fst.dll", + "sherpa-onnx-kaldifst-core.dll", "sherpa-onnx-portaudio.dll", "ucd.dll", ] @@ -211,7 +211,7 @@ def build_extension(self, ext: setuptools.extension.Extension): binaries = get_binaries() for f in binaries: - suffix = "" if (".dll" in f or ".lib" in f) else suffix + suffix = "" if ".dll" in f else suffix src_file = install_dir / "bin" / (f + suffix) if not src_file.is_file(): src_file = install_dir / "lib" / (f + suffix) diff --git a/cmake/kaldi-decoder.cmake b/cmake/kaldi-decoder.cmake index b78ece58f..aa937b3e4 100644 --- a/cmake/kaldi-decoder.cmake +++ b/cmake/kaldi-decoder.cmake @@ -1,9 +1,9 @@ function(download_kaldi_decoder) include(FetchContent) - set(kaldi_decoder_URL "https://github.com/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.5.tar.gz") - set(kaldi_decoder_URL2 "https://hub.nuaa.cf/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.5.tar.gz") - set(kaldi_decoder_HASH "SHA256=f663e58aef31b33cd8086eaa09ff1383628039845f31300b5abef817d8cc2fff") + set(kaldi_decoder_URL "https://github.com/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.6.tar.gz") + set(kaldi_decoder_URL2 "https://hub.nuaa.cf/k2-fsa/kaldi-decoder/archive/refs/tags/v0.2.6.tar.gz") + set(kaldi_decoder_HASH "SHA256=b13c78b37495cafc6ef3f8a7b661b349c55a51abbd7f7f42f389408dcf86a463") set(KALDI_DECODER_BUILD_PYTHON OFF CACHE BOOL "" FORCE) set(KALDI_DECODER_ENABLE_TESTS OFF CACHE BOOL "" FORCE) @@ -12,11 +12,11 @@ function(download_kaldi_decoder) # If you don't have access to the Internet, # please pre-download kaldi-decoder set(possible_file_locations - $ENV{HOME}/Downloads/kaldi-decoder-0.2.5.tar.gz - ${CMAKE_SOURCE_DIR}/kaldi-decoder-0.2.5.tar.gz - ${CMAKE_BINARY_DIR}/kaldi-decoder-0.2.5.tar.gz - /tmp/kaldi-decoder-0.2.5.tar.gz - /star-fj/fangjun/download/github/kaldi-decoder-0.2.5.tar.gz + $ENV{HOME}/Downloads/kaldi-decoder-0.2.6.tar.gz + ${CMAKE_SOURCE_DIR}/kaldi-decoder-0.2.6.tar.gz + ${CMAKE_BINARY_DIR}/kaldi-decoder-0.2.6.tar.gz + /tmp/kaldi-decoder-0.2.6.tar.gz + /star-fj/fangjun/download/github/kaldi-decoder-0.2.6.tar.gz ) foreach(f IN LISTS possible_file_locations) diff --git a/cmake/kaldifst.cmake b/cmake/kaldifst.cmake index 3b5ce3ba2..5e2130dbe 100644 --- a/cmake/kaldifst.cmake +++ b/cmake/kaldifst.cmake @@ -1,18 +1,18 @@ function(download_kaldifst) include(FetchContent) - set(kaldifst_URL "https://github.com/k2-fsa/kaldifst/archive/refs/tags/v1.7.10.tar.gz") - set(kaldifst_URL2 "https://hub.nuaa.cf/k2-fsa/kaldifst/archive/refs/tags/v1.7.10.tar.gz") - set(kaldifst_HASH "SHA256=7f7b3173a6584a6b1987f65ae7af2ac453d66b845f875a9d31074b8d2cd0de54") + set(kaldifst_URL "https://github.com/k2-fsa/kaldifst/archive/refs/tags/v1.7.11.tar.gz") + set(kaldifst_URL2 "https://hub.nuaa.cf/k2-fsa/kaldifst/archive/refs/tags/v1.7.11.tar.gz") + set(kaldifst_HASH "SHA256=b43b3332faa2961edc730e47995a58cd4e22ead21905d55b0c4a41375b4a525f") # If you don't have access to the Internet, # please pre-download kaldifst set(possible_file_locations - $ENV{HOME}/Downloads/kaldifst-1.7.10.tar.gz - ${CMAKE_SOURCE_DIR}/kaldifst-1.7.10.tar.gz - ${CMAKE_BINARY_DIR}/kaldifst-1.7.10.tar.gz - /tmp/kaldifst-1.7.10.tar.gz - /star-fj/fangjun/download/github/kaldifst-1.7.10.tar.gz + $ENV{HOME}/Downloads/kaldifst-1.7.11.tar.gz + ${CMAKE_SOURCE_DIR}/kaldifst-1.7.11.tar.gz + ${CMAKE_BINARY_DIR}/kaldifst-1.7.11.tar.gz + /tmp/kaldifst-1.7.11.tar.gz + /star-fj/fangjun/download/github/kaldifst-1.7.11.tar.gz ) foreach(f IN LISTS possible_file_locations) @@ -51,6 +51,7 @@ function(download_kaldifst) ) set_target_properties(kaldifst_core PROPERTIES OUTPUT_NAME "sherpa-onnx-kaldifst-core") + # installed in ./kaldi-decoder.cmake endfunction() download_kaldifst() diff --git a/cmake/openfst.cmake b/cmake/openfst.cmake index c964c14a4..59d4f9fc3 100644 --- a/cmake/openfst.cmake +++ b/cmake/openfst.cmake @@ -3,18 +3,18 @@ function(download_openfst) include(FetchContent) - set(openfst_URL "https://github.com/csukuangfj/openfst/archive/refs/tags/sherpa-onnx-2024-05-22-2.tar.gz") - set(openfst_URL2 "https://hub.nuaa.cf/csukuangfj/openfst/archive/refs/tags/sherpa-onnx-2024-05-22-2.tar.gz") - set(openfst_HASH "SHA256=ec52d32ab46ac884d77c87918155ca9d0cae424095ce3bd7e3cc7eaab8235a39") + set(openfst_URL "https://github.com/csukuangfj/openfst/archive/refs/tags/sherpa-onnx-2024-06-13.tar.gz") + set(openfst_URL2 "https://hub.nuaa.cf/csukuangfj/openfst/archive/refs/tags/sherpa-onnx-2024-06-13.tar.gz") + set(openfst_HASH "SHA256=f10a71c6b64d89eabdc316d372b956c30c825c7c298e2f20c780320e8181ffb6") # If you don't have access to the Internet, # please pre-download it set(possible_file_locations - $ENV{HOME}/Downloads/openfst-sherpa-onnx-2024-05-22-2.tar.gz - ${CMAKE_SOURCE_DIR}/openfst-sherpa-onnx-2024-05-22-2.tar.gz - ${CMAKE_BINARY_DIR}/openfst-sherpa-onnx-2024-05-22-2.tar.gz - /tmp/openfst-sherpa-onnx-2024-05-22-2.tar.gz - /star-fj/fangjun/download/github/openfst-sherpa-onnx-2024-05-22-2.tar.gz + $ENV{HOME}/Downloads/openfst-sherpa-onnx-2024-06-13.tar.gz + ${CMAKE_SOURCE_DIR}/openfst-sherpa-onnx-2024-06-13.tar.gz + ${CMAKE_BINARY_DIR}/openfst-sherpa-onnx-2024-06-13.tar.gz + /tmp/openfst-sherpa-onnx-2024-06-13.tar.gz + /star-fj/fangjun/download/github/openfst-sherpa-onnx-2024-06-13.tar.gz ) foreach(f IN LISTS possible_file_locations) @@ -27,7 +27,7 @@ function(download_openfst) endforeach() set(HAVE_BIN OFF CACHE BOOL "" FORCE) - set(HAVE_SCRIPT ON CACHE BOOL "" FORCE) + set(HAVE_SCRIPT OFF CACHE BOOL "" FORCE) set(HAVE_COMPACT OFF CACHE BOOL "" FORCE) set(HAVE_COMPRESS OFF CACHE BOOL "" FORCE) set(HAVE_CONST OFF CACHE BOOL "" FORCE) @@ -70,8 +70,6 @@ function(download_openfst) add_subdirectory(${openfst_SOURCE_DIR} ${openfst_BINARY_DIR} EXCLUDE_FROM_ALL) set(openfst_SOURCE_DIR ${openfst_SOURCE_DIR} PARENT_SCOPE) - # Rename libfst.so.6 to libsherpa-onnx-fst.so.6 to avoid potential conflicts - # when sherpa-onnx is installed. set_target_properties(fst PROPERTIES OUTPUT_NAME "sherpa-onnx-fst") set_target_properties(fstfar PROPERTIES OUTPUT_NAME "sherpa-onnx-fstfar") diff --git a/dart-api-examples/README.md b/dart-api-examples/README.md new file mode 100644 index 000000000..930037160 --- /dev/null +++ b/dart-api-examples/README.md @@ -0,0 +1,18 @@ +# Introduction + +This directory contains examples for Dart API. + +You can find the package at +https://pub.dev/packages/sherpa_onnx + +## How to create an example in this folder + +```bash +dart create vad +cd vad + +# Edit pubspec.yaml and add sherpa_onnx to dependencies + +dart pub get +dart run +``` diff --git a/dart-api-examples/vad/.gitignore b/dart-api-examples/vad/.gitignore new file mode 100644 index 000000000..3a8579040 --- /dev/null +++ b/dart-api-examples/vad/.gitignore @@ -0,0 +1,3 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ diff --git a/dart-api-examples/vad/CHANGELOG.md b/dart-api-examples/vad/CHANGELOG.md new file mode 100644 index 000000000..effe43c82 --- /dev/null +++ b/dart-api-examples/vad/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.0 + +- Initial version. diff --git a/dart-api-examples/vad/README.md b/dart-api-examples/vad/README.md new file mode 100644 index 000000000..1dd7f68c1 --- /dev/null +++ b/dart-api-examples/vad/README.md @@ -0,0 +1,21 @@ +# Introduction + +This example shows how to use the Dart API from sherpa-onnx for voice activity detection (VAD). +Specifically, we use VAD to remove silences from a wave file. + +# Usage + +```bash +dart pub get + +wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx +wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/lei-jun-test.wav + +dart run \ + ./bin/vad.dart \ + --silero-vad ./silero_vad.onnx \ + --input-wav ./lei-jun-test.wav \ + --output-wav ./lei-jun-test-no-silence.wav +``` + +It should generate a file `lei-jun-test-no-silence.wav`, where silences are removed. diff --git a/dart-api-examples/vad/analysis_options.yaml b/dart-api-examples/vad/analysis_options.yaml new file mode 100644 index 000000000..dee8927aa --- /dev/null +++ b/dart-api-examples/vad/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/dart-api-examples/vad/bin/vad.dart b/dart-api-examples/vad/bin/vad.dart new file mode 100644 index 000000000..d981bad94 --- /dev/null +++ b/dart-api-examples/vad/bin/vad.dart @@ -0,0 +1,93 @@ +import 'dart:io'; +import 'dart:isolate'; +import 'dart:typed_data'; + +import 'package:args/args.dart'; +import 'package:path/path.dart' as p; +import 'package:sherpa_onnx/sherpa_onnx.dart' as sherpa_onnx; + +Future initSherpaOnnx() async { + var uri = await Isolate.resolvePackageUri( + Uri.parse('package:sherpa_onnx/sherpa_onnx.dart')); + + if (uri == null) { + print('File not found'); + exit(1); + } + String platform = ''; + if (Platform.isMacOS) { + platform = 'macos'; + } else if (Platform.isLinux) { + platform = 'linux'; + } else if (Platform.isWindows) { + platform = 'windows'; + } else { + throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); + } + + final libPath = p.join(p.dirname(p.fromUri(uri)), '..', platform); + sherpa_onnx.initBindings(libPath); +} + +void main(List arguments) async { + await initSherpaOnnx(); + + final parser = ArgParser() + ..addOption('silero-vad', help: 'Path to silero_vad.onnx') + ..addOption('input-wav', help: 'Path to input.wav') + ..addOption('output-wav', help: 'Path to output.wav'); + final res = parser.parse(arguments); + if (res['silero-vad'] == null || + res['input-wav'] == null || + res['output-wav'] == null) { + print(parser.usage); + exit(1); + } + + final sileroVad = res['silero-vad'] as String; + final inputWav = res['input-wav'] as String; + final outputWav = res['output-wav'] as String; + + final sileroVadConfig = sherpa_onnx.SileroVadModelConfig( + model: sileroVad, + minSilenceDuration: 0.25, + minSpeechDuration: 0.5, + ); + final config = sherpa_onnx.VadModelConfig( + sileroVad: sileroVadConfig, + numThreads: 1, + debug: true, + ); + + final vad = sherpa_onnx.VoiceActivityDetector( + config: config, bufferSizeInSeconds: 10); + + final waveData = sherpa_onnx.readWave(inputWav); + if (waveData.sampleRate != 16000) { + print('Only 16000 Hz is supported. Given: ${waveData.sampleRate}'); + exit(1); + } + + int numSamples = waveData.samples.length; + int numIter = numSamples ~/ config.sileroVad.windowSize; + + List> allSamples = []; + + for (int i = 0; i != numIter; ++i) { + int start = i * config.sileroVad.windowSize; + vad.acceptWaveform(Float32List.sublistView( + waveData.samples, start, start + config.sileroVad.windowSize)); + + if (vad.isDetected()) { + while (!vad.isEmpty()) { + allSamples.add(vad.front().samples); + vad.pop(); + } + } + } + + final s = Float32List.fromList(allSamples.expand((x) => x).toList()); + sherpa_onnx.writeWave( + filename: outputWav, samples: s, sampleRate: waveData.sampleRate); + print('Saved to ${outputWav}'); +} diff --git a/dart-api-examples/vad/pubspec.lock b/dart-api-examples/vad/pubspec.lock new file mode 100644 index 000000000..776660ec5 --- /dev/null +++ b/dart-api-examples/vad/pubspec.lock @@ -0,0 +1,402 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "5aaf60d96c4cd00fe7f21594b5ad6a1b699c80a27420f8a837f4d68473ef09e3" + url: "https://pub.dev" + source: hosted + version: "68.0.0" + _macros: + dependency: transitive + description: dart + source: sdk + version: "0.1.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "21f1d3720fd1c70316399d5e2bccaebb415c434592d778cce8acb967b8578808" + url: "https://pub.dev" + source: hosted + version: "6.5.0" + args: + dependency: transitive + description: + name: args + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + coverage: + dependency: transitive + description: + name: coverage + sha256: "3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + url: "https://pub.dev" + source: hosted + version: "0.7.1" + lints: + dependency: "direct dev" + description: + name: lints + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + url: "https://pub.dev" + source: hosted + version: "3.0.0" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + macros: + dependency: transitive + description: + name: macros + sha256: "12e8a9842b5a7390de7a781ec63d793527582398d16ea26c60fed58833c9ae79" + url: "https://pub.dev" + source: hosted + version: "0.1.0-main.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + meta: + dependency: transitive + description: + name: meta + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + url: "https://pub.dev" + source: hosted + version: "1.15.0" + mime: + dependency: transitive + description: + name: mime + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" + url: "https://pub.dev" + source: hosted + version: "1.0.5" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" + source: hosted + version: "1.9.0" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" + source: hosted + version: "1.1.2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + url: "https://pub.dev" + source: hosted + version: "0.10.12" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test: + dependency: "direct dev" + description: + name: test + sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" + url: "https://pub.dev" + source: hosted + version: "1.25.7" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + url: "https://pub.dev" + source: hosted + version: "0.7.2" + test_core: + dependency: transitive + description: + name: test_core + sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" + url: "https://pub.dev" + source: hosted + version: "0.6.4" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "360c4271613beb44db559547d02f8b0dc044741d0eeb9aa6ccdb47e8ec54c63a" + url: "https://pub.dev" + source: hosted + version: "14.2.3" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + url: "https://pub.dev" + source: hosted + version: "0.5.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078" + url: "https://pub.dev" + source: hosted + version: "0.1.5" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276 + url: "https://pub.dev" + source: hosted + version: "3.0.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" +sdks: + dart: ">=3.4.0 <4.0.0" diff --git a/dart-api-examples/vad/pubspec.yaml b/dart-api-examples/vad/pubspec.yaml new file mode 100644 index 000000000..e7c7bc1cc --- /dev/null +++ b/dart-api-examples/vad/pubspec.yaml @@ -0,0 +1,17 @@ +name: vad + +description: > + This example demonstrates how to use the Dart API for VAD (voice activity detection). + +version: 1.0.0 + +environment: + sdk: ^3.4.0 + +dependencies: + sherpa_onnx: ^0.0.3 + path: ^1.9.0 + args: ^2.5.0 + +dev_dependencies: + lints: ^3.0.0 diff --git a/dart-api-examples/vad/run.sh b/dart-api-examples/vad/run.sh new file mode 100755 index 000000000..0db5ebe10 --- /dev/null +++ b/dart-api-examples/vad/run.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -ex + +dart pub get + + +if [[ ! -f ./silero_vad.onnx ]]; then + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx +fi + +if [[ ! -f ./lei-jun-test.wav ]]; then + curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/lei-jun-test.wav +fi + +dart run \ + ./bin/vad.dart \ + --silero-vad ./silero_vad.onnx \ + --input-wav ./lei-jun-test.wav \ + --output-wav ./lei-jun-test-no-silence.wav + +ls -lh *.wav diff --git a/scripts/dotnet/generate.py b/scripts/dotnet/generate.py index 9e3443202..46514673f 100755 --- a/scripts/dotnet/generate.py +++ b/scripts/dotnet/generate.py @@ -104,9 +104,9 @@ def process_windows(s, rid): "piper_phonemize.dll", "sherpa-onnx-c-api.dll", "sherpa-onnx-core.dll", - "sherpa-onnx-fstfar.lib", - "sherpa-onnx-fst.lib", - "sherpa-onnx-kaldifst-core.lib", + "sherpa-onnx-fstfar.dll", + "sherpa-onnx-fst.dll", + "sherpa-onnx-kaldifst-core.dll", "ucd.dll", ] diff --git a/scripts/dotnet/run.sh b/scripts/dotnet/run.sh index 7aa3ae5e4..ed28dfad2 100755 --- a/scripts/dotnet/run.sh +++ b/scripts/dotnet/run.sh @@ -30,7 +30,7 @@ mkdir -p linux macos windows-x64 windows-x86 linux_wheel_filename=sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl linux_wheel=$src_dir/$linux_wheel_filename -macos_wheel_filename=sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_universal2.whl +macos_wheel_filename=sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_universal2.whl macos_wheel=$src_dir/$macos_wheel_filename windows_x64_wheel_filename=sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl diff --git a/sherpa-onnx/flutter/CHANGELOG.md b/sherpa-onnx/flutter/CHANGELOG.md new file mode 100644 index 000000000..d59aedaca --- /dev/null +++ b/sherpa-onnx/flutter/CHANGELOG.md @@ -0,0 +1,11 @@ +## 0.0.3 + +* Fix path separator on Windows. + +## 0.0.2 + +* Support specifying lib path. + +## 0.0.1 + +* Initial release. diff --git a/sherpa-onnx/flutter/lib/sherpa_onnx.dart b/sherpa-onnx/flutter/lib/sherpa_onnx.dart index 77988d501..ff968a3d8 100644 --- a/sherpa-onnx/flutter/lib/sherpa_onnx.dart +++ b/sherpa-onnx/flutter/lib/sherpa_onnx.dart @@ -14,24 +14,40 @@ export 'src/wave_writer.dart'; import 'src/sherpa_onnx_bindings.dart'; +String? _path; + final DynamicLibrary _dylib = () { if (Platform.isIOS) { throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); } if (Platform.isMacOS) { - return DynamicLibrary.open('libsherpa-onnx-c-api.dylib'); + if (_path == null) { + return DynamicLibrary.open('libsherpa-onnx-c-api.dylib'); + } else { + return DynamicLibrary.open('${_path}/libsherpa-onnx-c-api.dylib'); + } } + if (Platform.isAndroid || Platform.isLinux) { - return DynamicLibrary.open('libsherpa-onnx-c-api.so'); + if (_path == null) { + return DynamicLibrary.open('libsherpa-onnx-c-api.so'); + } else { + return DynamicLibrary.open('${_path}/libsherpa-onnx-c-api.so'); + } } if (Platform.isWindows) { - return DynamicLibrary.open('sherpa-onnx-c-api.dll'); + if (_path == null) { + return DynamicLibrary.open('sherpa-onnx-c-api.dll'); + } else { + return DynamicLibrary.open('${_path}\\sherpa-onnx-c-api.dll'); + } } throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}'); }(); -void initBindings() { +void initBindings([String? p]) { + _path ??= p; SherpaOnnxBindings.init(_dylib); } diff --git a/sherpa-onnx/flutter/lib/src/offline_recognizer.dart b/sherpa-onnx/flutter/lib/src/offline_recognizer.dart index 6b6c29fa7..633312424 100644 --- a/sherpa-onnx/flutter/lib/src/offline_recognizer.dart +++ b/sherpa-onnx/flutter/lib/src/offline_recognizer.dart @@ -1,7 +1,6 @@ // Copyright (c) 2024 Xiaomi Corporation import 'dart:convert'; import 'dart:ffi'; -import 'dart:typed_data'; import 'package:ffi/ffi.dart'; @@ -262,7 +261,7 @@ class OfflineRecognizer { final json = SherpaOnnxBindings.getOfflineStreamResultAsJson?.call(stream.ptr) ?? nullptr; - if (json == null) { + if (json == nullptr) { return OfflineRecognizerResult(text: '', tokens: [], timestamps: []); } diff --git a/sherpa-onnx/flutter/lib/src/offline_stream.dart b/sherpa-onnx/flutter/lib/src/offline_stream.dart index 4157886d3..0b6f9c866 100644 --- a/sherpa-onnx/flutter/lib/src/offline_stream.dart +++ b/sherpa-onnx/flutter/lib/src/offline_stream.dart @@ -28,7 +28,7 @@ class OfflineStream { final pList = p.asTypedList(n); pList.setAll(0, samples); - SherpaOnnxBindings.acceptWaveformOffline?.call(this.ptr, sampleRate, p, n); + SherpaOnnxBindings.acceptWaveformOffline?.call(ptr, sampleRate, p, n); calloc.free(p); } diff --git a/sherpa-onnx/flutter/lib/src/online_recognizer.dart b/sherpa-onnx/flutter/lib/src/online_recognizer.dart index 8445e9d75..538c68dda 100644 --- a/sherpa-onnx/flutter/lib/src/online_recognizer.dart +++ b/sherpa-onnx/flutter/lib/src/online_recognizer.dart @@ -1,7 +1,6 @@ // Copyright (c) 2024 Xiaomi Corporation import 'dart:convert'; import 'dart:ffi'; -import 'dart:typed_data'; import 'package:ffi/ffi.dart'; @@ -247,7 +246,7 @@ class OnlineRecognizer { final json = SherpaOnnxBindings.getOnlineStreamResultAsJson?.call(ptr, stream.ptr) ?? nullptr; - if (json == null) { + if (json == nullptr) { return OnlineRecognizerResult(text: '', tokens: [], timestamps: []); } diff --git a/sherpa-onnx/flutter/lib/src/online_stream.dart b/sherpa-onnx/flutter/lib/src/online_stream.dart index ad4875072..29b196221 100644 --- a/sherpa-onnx/flutter/lib/src/online_stream.dart +++ b/sherpa-onnx/flutter/lib/src/online_stream.dart @@ -28,8 +28,7 @@ class OnlineStream { final pList = p.asTypedList(n); pList.setAll(0, samples); - SherpaOnnxBindings.onlineStreamAcceptWaveform - ?.call(this.ptr, sampleRate, p, n); + SherpaOnnxBindings.onlineStreamAcceptWaveform?.call(ptr, sampleRate, p, n); calloc.free(p); } diff --git a/sherpa-onnx/flutter/lib/src/sherpa_onnx_bindings.dart b/sherpa-onnx/flutter/lib/src/sherpa_onnx_bindings.dart index 273b48e52..997bfc70e 100644 --- a/sherpa-onnx/flutter/lib/src/sherpa_onnx_bindings.dart +++ b/sherpa-onnx/flutter/lib/src/sherpa_onnx_bindings.dart @@ -553,13 +553,10 @@ typedef DestroyOnlineStreamNative = Void Function( typedef DestroyOnlineStream = void Function(Pointer); typedef OnlineStreamAcceptWaveformNative = Void Function( - Pointer, - Int32 sample_rate, - Pointer, - Int32 n); + Pointer, Int32, Pointer, Int32); typedef OnlineStreamAcceptWaveform = void Function( - Pointer, int sample_rate, Pointer, int n); + Pointer, int, Pointer, int); typedef OnlineStreamInputFinishedNative = Void Function( Pointer); diff --git a/sherpa-onnx/flutter/lib/src/vad.dart b/sherpa-onnx/flutter/lib/src/vad.dart index 5fe4392f4..7f8b412a1 100644 --- a/sherpa-onnx/flutter/lib/src/vad.dart +++ b/sherpa-onnx/flutter/lib/src/vad.dart @@ -106,8 +106,8 @@ class CircularBuffer { SherpaOnnxBindings.circularBufferReset?.call(this.ptr); } - int get size => SherpaOnnxBindings.circularBufferSize?.call(this.ptr) ?? 0; - int get head => SherpaOnnxBindings.circularBufferHead?.call(this.ptr) ?? 0; + int get size => SherpaOnnxBindings.circularBufferSize?.call(ptr) ?? 0; + int get head => SherpaOnnxBindings.circularBufferHead?.call(ptr) ?? 0; Pointer ptr; } @@ -159,38 +159,36 @@ class VoiceActivityDetector { final pList = p.asTypedList(n); pList.setAll(0, samples); - SherpaOnnxBindings.voiceActivityDetectorAcceptWaveform - ?.call(this.ptr, p, n); + SherpaOnnxBindings.voiceActivityDetectorAcceptWaveform?.call(ptr, p, n); calloc.free(p); } bool isEmpty() { final int empty = - SherpaOnnxBindings.voiceActivityDetectorEmpty?.call(this.ptr) ?? 0; + SherpaOnnxBindings.voiceActivityDetectorEmpty?.call(ptr) ?? 0; return empty == 1; } bool isDetected() { final int detected = - SherpaOnnxBindings.voiceActivityDetectorDetected?.call(this.ptr) ?? 0; + SherpaOnnxBindings.voiceActivityDetectorDetected?.call(ptr) ?? 0; return detected == 1; } void pop() { - SherpaOnnxBindings.voiceActivityDetectorPop?.call(this.ptr); + SherpaOnnxBindings.voiceActivityDetectorPop?.call(ptr); } void clear() { - SherpaOnnxBindings.voiceActivityDetectorClear?.call(this.ptr); + SherpaOnnxBindings.voiceActivityDetectorClear?.call(ptr); } SpeechSegment front() { final Pointer segment = - SherpaOnnxBindings.voiceActivityDetectorFront?.call(this.ptr) ?? - nullptr; + SherpaOnnxBindings.voiceActivityDetectorFront?.call(ptr) ?? nullptr; if (segment == nullptr) { return SpeechSegment(samples: Float32List(0), start: 0); } @@ -206,7 +204,7 @@ class VoiceActivityDetector { } void reset() { - SherpaOnnxBindings.voiceActivityDetectorReset?.call(this.ptr); + SherpaOnnxBindings.voiceActivityDetectorReset?.call(ptr); } Pointer ptr; diff --git a/sherpa-onnx/flutter/notes.md b/sherpa-onnx/flutter/notes.md index 946f08973..42d872e58 100644 --- a/sherpa-onnx/flutter/notes.md +++ b/sherpa-onnx/flutter/notes.md @@ -43,3 +43,20 @@ dart analyze FLUTTER_XCODE_ARCHS=arm64 FLUTTER_XCODE_ARCHS=x86_64 ``` + +## Examples + + - https://dart.dev/tools/pub/automated-publishing + + Use GitHub actions to publish + + - https://dart.dev/tools/pub/pubspec + + It describes the format of ./pubspec.yaml + + - https://github.com/folksable/blurhash_ffi/ + + It supports ios, android, linux, macos, and windows. + + - https://github.com/alexmercerind/dart_vlc + - https://github.com/dart-lang/native/tree/main/pkgs/jni diff --git a/sherpa-onnx/flutter/pubspec.yaml b/sherpa-onnx/flutter/pubspec.yaml index ce84f9d74..d216928da 100644 --- a/sherpa-onnx/flutter/pubspec.yaml +++ b/sherpa-onnx/flutter/pubspec.yaml @@ -1,17 +1,24 @@ name: sherpa_onnx + description: > - Dart bindings for sherpa-onnx. -repository: https://github.com/k2-fsa/sherpa-onnx/tree/main/sherpa-onnx/flutter + Speech recognition, speech synthesis, and speaker recognition using next-gen Kaldi + with onnxruntime without Internet connection. + +repository: https://github.com/k2-fsa/sherpa-onnx/tree/master/sherpa-onnx/flutter + +issue_tracker: https://github.com/k2-fsa/sherpa-onnx/issues +documentation: https://k2-fsa.github.io/sherpa/onnx/ + topics: - - speech-to-text - - text-to-speech + - speech-recognition + - speech-synthesis - speaker-identification - - spoken-language-identification - audio-tagging - voice-activity-detection # remember to change the version in macos/sherpa_onnx.podspec -version: 0.0.1 +version: 0.0.2 + homepage: https://github.com/k2-fsa/sherpa-onnx environment: @@ -22,30 +29,14 @@ dependencies: ffi: ^2.1.0 flutter: sdk: flutter - plugin_platform_interface: ^2.0.2 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^3.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - # The following section is specific to Flutter packages. flutter: - # This section identifies this Flutter project as a plugin project. - # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) - # which should be registered in the plugin registry. This is required for - # using method channels. - # The Android 'package' specifies package in which the registered class is. - # This is required for using method channels on Android. - # The 'ffiPlugin' specifies that native code should be built and bundled. - # This is required for using `dart:ffi`. - # All these are used by the tooling to maintain consistency when - # adding or updating assets for this project. - # - # Please refer to README.md for a detailed explanation. plugin: platforms: macos: @@ -54,34 +45,3 @@ flutter: ffiPlugin: true linux: ffiPlugin: true - - # To add assets to your plugin package, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # - # For details regarding assets in packages, see - # https://flutter.dev/assets-and-images/#from-packages - # - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # To add custom fonts to your plugin package, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts in packages, see - # https://flutter.dev/custom-fonts/#from-packages diff --git a/sherpa-onnx/flutter/windows/CMakeLists.txt b/sherpa-onnx/flutter/windows/CMakeLists.txt index 06fa598ca..a6a262ee4 100644 --- a/sherpa-onnx/flutter/windows/CMakeLists.txt +++ b/sherpa-onnx/flutter/windows/CMakeLists.txt @@ -19,9 +19,9 @@ set(sherpa_onnx_bundled_libraries "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-c-api.dll" "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-core.dll" "${CMAKE_CURRENT_SOURCE_DIR}/kaldi-decoder-core.dll" - "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-kaldifst-core.lib" - "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-fstfar.lib" - "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-fst.lib" + "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-kaldifst-core.dll" + "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-fstfar.dll" + "${CMAKE_CURRENT_SOURCE_DIR}/sherpa-onnx-fst.dll" "${CMAKE_CURRENT_SOURCE_DIR}/kaldi-native-fbank-core.dll" "${CMAKE_CURRENT_SOURCE_DIR}/piper_phonemize.dll" "${CMAKE_CURRENT_SOURCE_DIR}/espeak-ng.dll"