Skip to content

[BUG] sherpa-onnx.rn Android: OfflineSpeechDenoiser SIGABRT/CheckJNI — Kotlin OfflineSpeechDenoiserModelConfig missing dpdfnet field #411

Description

@brainlybai

Environment

  • expo-audio-studio version: n/a (this is a @siteed/sherpa-onnx.rn bug)
  • Package: @siteed/sherpa-onnx.rn 1.3.1-beta.1 (bundled sherpa-onnx binaries 1.13.0)
  • Expo SDK version: 55
  • Platform & OS version: Android 14 (emulator API 36, Pixel 8), arm64-v8a
  • Device: Android emulator with CheckJNI enabled (default on emulators / debug builds)

Note: filed against this repo because sherpa-onnx.rn lives in this monorepo. Not related to expo-audio-studio.

Description

On Android, constructing OfflineSpeechDenoiser with newFromFile aborts the process with SIGABRT under CheckJNI. The native JNI in libsherpa-onnx-jni.so calls GetFieldID("dpdfnet", ...) on OfflineSpeechDenoiserModelConfig, but the Kotlin data class doesn't declare that field, so CheckJNI aborts the process.

Logs

F libc: Fatal signal 6 (SIGABRT)
F DEBUG: #00 libc.so abort+160
F DEBUG: #01 libart.so art::Runtime::Abort
F DEBUG: #04 libart.so art::JavaVMExt::JniAbort
F DEBUG: #07 libart.so art::(anonymous namespace)::ScopedCheck::Check
F DEBUG: #08 libart.so art::(anonymous namespace)::CheckJNI::GetField
F DEBUG: #11 libsherpa-onnx-jni.so Java_com_k2fsa_sherpa_onnx_OfflineSpeechDenoiser_newFromFile+56
F DEBUG: #17 com.k2fsa.sherpa.onnx.OfflineSpeechDenoiser.<init>

Root cause

The prebuilt libsherpa-onnx-jni.so (sherpa-onnx 1.13.0 binaries) calls:

// sherpa-onnx/jni/speech-denoiser.cc — GetOfflineSpeechDenoiserModelConfig
fid = env->GetFieldID(cls, "dpdfnet",
    "Lcom/k2fsa/sherpa/onnx/OfflineSpeechDenoiserDpdfNetModelConfig;");

But packages/sherpa-onnx.rn/android/src/main/kotlin/com/k2fsa/sherpa/onnx/OfflineSpeechDenoiser.kt only declares gtcrn, numThreads, debug, provider. The dpdfnet field and OfflineSpeechDenoiserDpdfNetModelConfig class are missing. CheckJNI sees the missing field and aborts. Without CheckJNI it would still throw NoSuchFieldError.

iOS uses Swift handlers under ios/handlers/ and is unaffected.

Configuration

const config = {
    model: { gtcrn: { model: '/abs/path/to/gtcrn_simple.onnx' } },
};
await SpeechDenoiserService.init(config); // crashes inside newFromFile

Expected Behavior

OfflineSpeechDenoiser(config) initializes successfully on Android.

Actual Behavior

Process aborts with SIGABRT inside Java_..._OfflineSpeechDenoiser_newFromFile.

Fix

Add the missing OfflineSpeechDenoiserDpdfNetModelConfig data class and the dpdfnet field on OfflineSpeechDenoiserModelConfig, mirroring upstream sherpa-onnx Java bindings.

PR: #412

Checklist

  • Tested on latest published version (1.3.1-beta.1)
  • Verified the prebuilt libsherpa-onnx-jni.so references dpdfnet (binary grep)
  • Verified upstream sherpa-onnx/jni/speech-denoiser.cc queries dpdfnet unconditionally
  • Applied the fix locally via pnpm patch — denoiser init no longer aborts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions