Browse Source

Fix building the binary sherpa-ncnn for Android (#70)

* Fix building the binary sherpa-ncnn for Android

* small fixes
Fangjun Kuang 2 years ago
parent
commit
fae704676a

+ 1 - 1
CMakeLists.txt

@@ -25,7 +25,7 @@ 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)
-
+option(SHERPA_NCNN_ENABLE_BINARY "Whether to build the binary sherpa-ncnn" ON)
 
 if(DEFINED ANDROID_ABI)
   message(STATUS "Set SHERPA_NCNN_ENABLE_JNI to ON for Android")

+ 1 - 0
build-android-arm64-v8a-with-vulkan.sh

@@ -112,6 +112,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake"
     -DBUILD_SHARED_LIBS=ON \
     -DNCNN_SYSTEM_GLSLANG=ON \
     -DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+    -DSHERPA_NCNN_ENABLE_BINARY=OFF \
     -DCMAKE_INSTALL_PREFIX=./install \
     -DANDROID_ABI="arm64-v8a" \
     -DNCNN_VULKAN=ON \

+ 32 - 0
build-android-arm64-v8a.sh

@@ -48,8 +48,40 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake"
     -DCMAKE_BUILD_TYPE=Release \
     -DBUILD_SHARED_LIBS=ON \
     -DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+    -DSHERPA_NCNN_ENABLE_BINARY=OFF \
     -DCMAKE_INSTALL_PREFIX=./install \
     -DANDROID_ABI="arm64-v8a" \
     -DANDROID_PLATFORM=android-21 ..
 make VERBOSE=1 -j4
 make install/strip
+
+# Note: If you set SHERPA_NCNN_ENABLE_BINARY=ON, it will
+# generate a binary sherpa-ncnn in $dir/install/bin, which can be run on Android
+# with the following commands:
+#
+# 1. Copy sherpa-ncnn and its dependencies to Android
+#
+#   cd build-android-arm64-v8a/install/lib
+#   adb push ./lib*.so /data/local/tmp
+#   cd ../bin
+#   adb push ./sherpa-ncnn /data/local/tmp
+#
+# 2. Login into Android
+#
+#   adb shell
+#   cd /data/local/tmp
+#   ./sherpa-ncnn
+#
+# which shows the following error log:
+#
+#  CANNOT LINK EXECUTABLE "./sherpa-ncnn": library "libsherpa-ncnn-core.so" not found: needed by main executable
+#
+# Please run:
+#
+#  export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
+#
+# and then you can run:
+#
+#  ./sherpa-ncnn
+#
+# It should show the help message of sherpa-ncnn.

+ 1 - 0
build-android-armv7-eabi.sh

@@ -47,6 +47,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake"
     -DCMAKE_BUILD_TYPE=Release \
     -DBUILD_SHARED_LIBS=ON \
     -DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+    -DSHERPA_NCNN_ENABLE_BINARY=OFF \
     -DCMAKE_INSTALL_PREFIX=./install \
     -DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \
     -DANDROID_PLATFORM=android-21 ..

+ 1 - 0
build-android-x86-64.sh

@@ -49,6 +49,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake"
     -DCMAKE_BUILD_TYPE=Release \
     -DBUILD_SHARED_LIBS=ON \
     -DSHERPA_NCNN_ENABLE_PORTAUDIO=OFF \
+    -DSHERPA_NCNN_ENABLE_BINARY=OFF \
     -DCMAKE_INSTALL_PREFIX=./install \
     -DANDROID_ABI="x86_64" \
     -DANDROID_PLATFORM=android-21 ..

+ 1 - 1
sherpa-ncnn/csrc/CMakeLists.txt

@@ -19,7 +19,7 @@ target_link_libraries(sherpa-ncnn-core PUBLIC kaldi-native-fbank-core ncnn)
 install(TARGETS sherpa-ncnn-core DESTINATION lib)
 
 if(NOT SHERPA_NCNN_ENABLE_PYTHON)
-  if(NOT DEFINED ANDROID_ABI)
+  if(SHERPA_NCNN_ENABLE_BINARY)
     add_executable(sherpa-ncnn sherpa-ncnn.cc)
     target_link_libraries(sherpa-ncnn PRIVATE sherpa-ncnn-core)
     install(TARGETS sherpa-ncnn DESTINATION bin)

+ 23 - 12
sherpa-ncnn/csrc/recognizer.cc

@@ -40,20 +40,30 @@ std::string DecoderConfig::ToString() const {
   return os.str();
 }
 
-Recognizer::Recognizer(
-#if __ANDROID_API__ >= 9
-    AAssetManager *mgr,
-#endif
-    const DecoderConfig &decoder_conf, const ModelConfig &model_conf,
-    const knf::FbankOptions &fbank_opts)
-    :
+Recognizer::Recognizer(const DecoderConfig &decoder_conf,
+                       const ModelConfig &model_conf,
+                       const knf::FbankOptions &fbank_opts)
+    : model_(Model::Create(model_conf)),
+      sym_(std::make_unique<SymbolTable>(model_conf.tokens)),
+      endpoint_(std::make_unique<Endpoint>(decoder_conf.endpoint_config)) {
+  if (decoder_conf.method == "modified_beam_search") {
+    decoder_ = std::make_unique<ModifiedBeamSearchDecoder>(
+        decoder_conf, model_.get(), fbank_opts, sym_.get(), endpoint_.get());
+  } else if (decoder_conf.method == "greedy_search") {
+    decoder_ = std::make_unique<GreedySearchDecoder>(
+        decoder_conf, model_.get(), fbank_opts, sym_.get(), endpoint_.get());
+  } else {
+    NCNN_LOGE("Unsupported decoding method: %s\n", decoder_conf.method.c_str());
+    exit(-1);
+  }
+}
+
 #if __ANDROID_API__ >= 9
-      model_(Model::Create(mgr, model_conf)),
+Recognizer::Recognizer(AAssetManager *mgr, const DecoderConfig &decoder_conf,
+                       const ModelConfig &model_conf,
+                       const knf::FbankOptions &fbank_opts)
+    : model_(Model::Create(mgr, model_conf)),
       sym_(std::make_unique<SymbolTable>(mgr, model_conf.tokens)),
-#else
-      model_(Model::Create(model_conf)),
-      sym_(std::make_unique<SymbolTable>(model_conf.tokens)),
-#endif
       endpoint_(std::make_unique<Endpoint>(decoder_conf.endpoint_config)) {
   if (decoder_conf.method == "modified_beam_search") {
     decoder_ = std::make_unique<ModifiedBeamSearchDecoder>(
@@ -66,6 +76,7 @@ Recognizer::Recognizer(
     exit(-1);
   }
 }
+#endif
 
 void Recognizer::AcceptWaveform(float sample_rate, const float *input_buffer,
                                 int32_t frames_per_buffer) {

+ 6 - 4
sherpa-ncnn/csrc/recognizer.h

@@ -88,12 +88,14 @@ class Recognizer {
  public:
   /** Construct an instance of OnlineRecognizer.
    */
-  Recognizer(
+  Recognizer(const DecoderConfig &decoder_conf, const ModelConfig &model_conf,
+             const knf::FbankOptions &fbank_opts);
+
 #if __ANDROID_API__ >= 9
-      AAssetManager *mgr,
+  Recognizer(AAssetManager *mgr, const DecoderConfig &decoder_conf,
+             const ModelConfig &model_conf,
+             const knf::FbankOptions &fbank_opts);
 #endif
-      const DecoderConfig &decoder_conf, const ModelConfig &model_conf,
-      const knf::FbankOptions &fbank_opts);
 
   ~Recognizer() = default;