瀏覽代碼

Add test for JNI (#63)

Fangjun Kuang 2 年之前
父節點
當前提交
b4bd94d95b

+ 4 - 0
.github/scripts/AssetManager.kt

@@ -0,0 +1,4 @@
+package android.content.res
+
+// a dummy class for testing only
+class AssetManager

+ 29 - 0
.github/scripts/Main.kt

@@ -0,0 +1,29 @@
+package com.k2fsa.sherpa.ncnn
+
+import android.content.res.AssetManager
+
+fun main() {
+  var model = SherpaNcnn(
+      assetManager = AssetManager(),
+      modelConfig = getModelConfig(type = 1, useGPU = false)!!,
+      decoderConfig = getDecoderConfig(enableEndpoint = true),
+      fbankConfig = getFbankConfig(),
+  )
+
+  var samples = WaveReader.readWave(
+      assetManager = AssetManager(),
+      filename = "./sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/2.wav"
+  )
+
+  model.decodeSamples(samples!!)
+
+  var tail_paddings = FloatArray(8000) // 0.5 seconds
+  model.decodeSamples(tail_paddings)
+
+  model.inputFinished()
+  println(model.text)
+
+  return
+
+
+}

+ 1 - 0
.github/scripts/SherpaNcnn.kt

@@ -0,0 +1 @@
+../../android/SherpaNcnn/app/src/main/java/com/k2fsa/sherpa/ncnn/SherpaNcnn.kt

+ 1 - 0
.github/scripts/WaveReader.kt

@@ -0,0 +1 @@
+../../android/SherpaNcnn/app/src/main/java/com/k2fsa/sherpa/ncnn/WaveReader.kt

+ 9 - 0
.github/scripts/note.md

@@ -0,0 +1,9 @@
+# Install kotlin on macOS
+
+Assume that you have installed jdk.
+
+```bash
+wget https://github.com/JetBrains/kotlin/releases/download/v1.8.0/kotlin-compiler-1.8.0.zip
+unzip kotlin-compiler-1.8.0.zip
+export PATH=$PWD/kotlinc/bin:$PATH
+```

+ 30 - 0
.github/scripts/test-jni.sh

@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+set -e
+
+mkdir -p build
+cd build
+
+cmake \
+  -D BUILD_SHARED_LIBS=ON \
+  -D SHERPA_NCNN_ENABLE_JNI=ON \
+  -D SHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+  -D SHERPA_NCNN_ENABLE_PYTHON=OFF \
+  -D SHERPA_NCNN_ENABLE_JNI=ON \
+  ..
+
+make -j4
+ls -lh lib
+
+cd ..
+
+export LD_LIBRARY_PATH=$PWD/build/lib:$LD_LIBRARY_PATH
+
+cd .github/scripts/
+
+git lfs install
+git clone https://huggingface.co/csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-06
+
+kotlinc-jvm -include-runtime -d main.jar Main.kt WaveReader.kt SherpaNcnn.kt AssetManager.kt
+
+java -Djava.library.path=../../build/lib -jar main.jar

+ 1 - 1
.github/scripts/test-recognizer.py

@@ -18,7 +18,7 @@ def main():
         num_threads=4,
     )
 
-    filename = "./sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/1.wav"
+    filename = "./sherpa-ncnn-conv-emformer-transducer-2022-12-06/test_wavs/5.wav"
     with wave.open(filename) as f:
         assert f.getframerate() == recognizer.sample_rate, (
             f.getframerate(),

+ 60 - 0
.github/workflows/jni.yaml

@@ -0,0 +1,60 @@
+name: jni
+
+on:
+  push:
+    branches:
+      - master
+      - jni-test-2023-01-09
+    paths:
+      - '.github/workflows/jni.yaml'
+      - 'CMakeLists.txt'
+      - 'cmake/**'
+      - 'sherpa-ncnn/csrc/*'
+      - 'sherpa-ncnn/jni/*'
+      - '.github/scripts/test-jni.sh'
+  pull_request:
+    branches:
+      - master
+    paths:
+      - '.github/workflows/jni.yaml'
+      - 'CMakeLists.txt'
+      - 'cmake/**'
+      - 'sherpa-ncnn/csrc/*'
+      - 'sherpa-ncnn/jni/*'
+      - '.github/scripts/test-jni.sh'
+
+concurrency:
+  group: jni-${{ github.ref }}
+  cancel-in-progress: true
+
+permissions:
+  contents: read
+
+jobs:
+  jni:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, macos-latest]
+
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+
+      - name: Display kotlin version
+        shell: bash
+        run: |
+          kotlinc -version
+
+      - name: Display java version
+        shell: bash
+        run: |
+          java -version
+          echo "JAVA_HOME is: ${JAVA_HOME}"
+
+      - name:  Run JNI test
+        shell: bash
+        run: |
+          .github/scripts/test-jni.sh

+ 1 - 1
.github/workflows/linux-macos-windows.yaml

@@ -45,7 +45,7 @@ jobs:
         if: startsWith(matrix.os, 'windows')
         uses: microsoft/setup-msbuild@v1.0.2
 
-      - name: Configure Cmake
+      - name: Configure CMake
         shell: bash
         run: |
           mkdir build

+ 0 - 36
.github/workflows/publish-to-pypi.yaml

@@ -1,36 +0,0 @@
-name: Publish to PyPI
-
-on:
-  push:
-    tags:
-      - '*'
-
-jobs:
-  pypi:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup Python
-        uses: actions/setup-python@v2
-        with:
-          python-version: "3.8"
-
-      - name: Install Python dependencies
-        shell: bash
-        run: |
-          python3 -m pip install --upgrade pip
-          python3 -m pip install wheel twine setuptools
-
-      - name: Build
-        shell: bash
-        run: |
-          python3 setup.py sdist
-          ls -l dist/*
-
-      - name: Publish wheels to PyPI
-        env:
-          TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
-          TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
-        run: |
-          twine upload dist/sherpa-ncnn-*.tar.gz

+ 16 - 10
.github/workflows/test-pip-install.yaml

@@ -3,13 +3,18 @@ name: test-pip-install
 on:
   push:
     branches:
-      - master
-  pull_request:
-    branches:
-      - master
+      - nightly
+  schedule:
+    # minute (0-59)
+    # hour (0-23)
+    # day of the month (1-31)
+    # month (1-12)
+    # day of the week (0-6)
+    # nightly test at 22:50 UTC time every day
+    - cron: "50 22 * * *"
 
 concurrency:
-  group: linux-macos-windows-${{ github.ref }}
+  group: test_pip_install-${{ github.ref }}
   cancel-in-progress: true
 
 permissions:
@@ -42,18 +47,19 @@ jobs:
       - name: Display Python version
         run: python -c "import sys; print(sys.version)"
 
-      - name: Install sherpa-ncnn
-        shell: bash
-        run: |
-          pip3 install --verbose -U sherpa-ncnn
-
       - name: Download pretrained model and test-data
         shell: bash
         run: |
           git lfs install
           git clone https://huggingface.co/csukuangfj/sherpa-ncnn-conv-emformer-transducer-2022-12-06
 
+      - name: Install sherpa-ncnn
+        shell: bash
+        run: |
+          pip3 install --verbose -U sherpa-ncnn
+
       - name: Run test
         shell: bash
         run: |
           python3 .github/scripts/test-recognizer.py
+

+ 2 - 0
.gitignore

@@ -6,3 +6,5 @@ run*.sh
 dist/
 .DS_Store
 tags
+*.jar
+sherpa-ncnn-conv-emformer-transducer-2022-12-06

+ 8 - 0
CMakeLists.txt

@@ -24,9 +24,17 @@ set(CMAKE_BUILD_RPATH ${SHERPA_NCNN_RPATH_ORIGIN})
 option(BUILD_SHARED_LIBS "Whether to build shared libraries" OFF)
 option(SHERPA_NCNN_ENABLE_PYTHON "Whether to build Python" OFF)
 option(SHERPA_NCNN_ENABLE_PORTAUDIO "Whether to build with portaudio" ON)
+option(SHERPA_NCNN_ENABLE_JNI "Whether to build JNI internface" OFF)
+
+
+if(DEFINED ANDROID_ABI)
+  message(STATUS "Set SHERPA_NCNN_ENABLE_JNI to ON for Android")
+  set(SHERPA_NCNN_ENABLE_JNI ON CACHE BOOL "" FORCE)
+endif()
 
 message(STATUS "BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}")
 message(STATUS "SHERPA_NCNN_ENABLE_PYTHON ${SHERPA_NCNN_ENABLE_PYTHON}")
+message(STATUS "SHERPA_NCNN_ENABLE_JNI ${SHERPA_NCNN_ENABLE_JNI}")
 
 if(NOT CMAKE_BUILD_TYPE)
   message(STATUS "No CMAKE_BUILD_TYPE given, default to Release")

+ 1 - 1
sherpa-ncnn/CMakeLists.txt

@@ -1,6 +1,6 @@
 add_subdirectory(csrc)
 
-if(DEFINED ANDROID_ABI)
+if(SHERPA_NCNN_ENABLE_JNI)
   add_subdirectory(jni)
 endif()
 

+ 9 - 0
sherpa-ncnn/jni/CMakeLists.txt

@@ -1,5 +1,14 @@
 include_directories(${CMAKE_SOURCE_DIR})
 
+if(NOT DEFINED ANDROID_ABI)
+  if(NOT DEFINED ENV{JAVA_HOME})
+    message(FATAL_ERROR "Please set the environment variable JAVA_HOME")
+  endif()
+  include_directories($ENV{JAVA_HOME}/include)
+  include_directories($ENV{JAVA_HOME}/include/linux)
+  include_directories($ENV{JAVA_HOME}/include/darwin)
+endif()
+
 add_library(sherpa-ncnn-jni jni.cc)
 target_link_libraries(sherpa-ncnn-jni sherpa-ncnn-core)
 install(TARGETS sherpa-ncnn-jni DESTINATION lib)

+ 32 - 9
sherpa-ncnn/jni/jni.cc

@@ -26,8 +26,13 @@
 
 #include <strstream>
 
+#if __ANDROID_API__ >= 9
 #include "android/asset_manager.h"
 #include "android/asset_manager_jni.h"
+#else
+#include <fstream>
+#endif
+
 #include "sherpa-ncnn/csrc/recognizer.h"
 #include "sherpa-ncnn/csrc/wave-reader.h"
 
@@ -37,12 +42,19 @@ namespace sherpa_ncnn {
 
 class SherpaNcnn {
  public:
-  SherpaNcnn(AAssetManager *mgr,
-             const sherpa_ncnn::DecoderConfig &decoder_config,
-             const ModelConfig &model_config,
-             const knf::FbankOptions &fbank_opts)
-      : recognizer_(mgr, decoder_config, model_config, fbank_opts),
-        tail_padding_(16000 * 0.32, 0) {}
+  SherpaNcnn(
+#if __ANDROID_API__ >= 9
+      AAssetManager *mgr,
+#endif
+      const sherpa_ncnn::DecoderConfig &decoder_config,
+      const ModelConfig &model_config, const knf::FbankOptions &fbank_opts)
+      : recognizer_(
+#if __ANDROID_API__ >= 9
+            mgr,
+#endif
+            decoder_config, model_config, fbank_opts),
+        tail_padding_(16000 * 0.32, 0) {
+  }
 
   void DecodeSamples(float sample_rate, const float *samples, int32_t n) {
     recognizer_.AcceptWaveform(sample_rate, samples, n);
@@ -298,10 +310,12 @@ SHERPA_EXTERN_C
 JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_ncnn_SherpaNcnn_new(
     JNIEnv *env, jobject /*obj*/, jobject asset_manager, jobject _model_config,
     jobject _decoder_config, jobject _fbank_config) {
+#if __ANDROID_API__ >= 9
   AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager);
   if (!mgr) {
     NCNN_LOGE("Failed to get asset manager: %p", mgr);
   }
+#endif
 
   auto model_config = sherpa_ncnn::GetModelConfig(env, _model_config);
   auto decoder_config = sherpa_ncnn::GetDecoderConfig(env, _decoder_config);
@@ -313,8 +327,11 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_ncnn_SherpaNcnn_new(
   knf::FbankOptions fbank_opts =
       sherpa_ncnn::GetFbankOptions(env, _fbank_config);
 
-  auto model = new sherpa_ncnn::SherpaNcnn(mgr, decoder_config, model_config,
-                                           fbank_opts);
+  auto model = new sherpa_ncnn::SherpaNcnn(
+#if __ANDROID_API__ >= 9
+      mgr,
+#endif
+      decoder_config, model_config, fbank_opts);
 
   return (jlong)model;
 }
@@ -373,12 +390,13 @@ JNIEXPORT jfloatArray JNICALL
 Java_com_k2fsa_sherpa_ncnn_WaveReader_00024Companion_readWave(
     JNIEnv *env, jclass /*cls*/, jobject asset_manager, jstring filename,
     jfloat expected_sample_rate) {
+  const char *p_filename = env->GetStringUTFChars(filename, nullptr);
+#if __ANDROID_API__ >= 9
   AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager);
   if (!mgr) {
     NCNN_LOGE("Failed to get asset manager: %p", mgr);
     return nullptr;
   }
-  const char *p_filename = env->GetStringUTFChars(filename, nullptr);
 
   AAsset *asset = AAssetManager_open(mgr, p_filename, AASSET_MODE_BUFFER);
   size_t asset_length = AAsset_getLength(asset);
@@ -386,12 +404,17 @@ Java_com_k2fsa_sherpa_ncnn_WaveReader_00024Companion_readWave(
   AAsset_read(asset, buffer.data(), asset_length);
 
   std::istrstream is(buffer.data(), asset_length);
+#else
+  std::ifstream is(p_filename, std::ios::binary);
+#endif
 
   bool is_ok = false;
   std::vector<float> samples =
       sherpa_ncnn::ReadWave(is, expected_sample_rate, &is_ok);
 
+#if __ANDROID_API__ >= 9
   AAsset_close(asset);
+#endif
   env->ReleaseStringUTFChars(filename, p_filename);
 
   if (!is_ok) {