Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/run-java-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ jobs:
# Delete model files to save space
rm -rf sherpa-onnx-punct-*

- name: Run java test (Offline add diacritics)
shell: bash
run: |
cd ./java-api-examples
./run-offline-add-diacritics.sh
# Delete model files to save space
rm -rf catt_eo_model_onnx

- name: Run java test (speaker diarization)
shell: bash
run: |
Expand Down
38 changes: 38 additions & 0 deletions java-api-examples/OfflineAddDiacritics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2026 Matias Lin

// This file shows how to use a CATT diacritization model to add diacritics to Arabic text.
import com.k2fsa.sherpa.onnx.*;

public class OfflineAddDiacritics {
public static void main(String[] args) {
// please download the model from
// https://github.com/abjadai/catt/releases/download/v2/eo_model_onnx.zip
String cattEncoder = "./catt_eo_model_onnx/encoder.onnx";
String cattDecoder = "./catt_eo_model_onnx/decoder.onnx";
OfflineDiacritizationModelConfig modelConfig =
OfflineDiacritizationModelConfig.builder()
.setCattEncoder(cattEncoder)
.setCattDecoder(cattDecoder)
.setNumThreads(1)
.setDebug(true)
.build();
OfflineDiacritizationConfig config =
OfflineDiacritizationConfig.builder().setModel(modelConfig).build();

OfflineDiacritization diacrt = new OfflineDiacritization(config);

String[] sentences =
new String[] {
"وقالت مجلة نيوزويك الأمريكية التحديث الجديد ل إنستجرام يمكن أن يساهم في إيقاف وكشف الحسابات المزورة بسهولة شديدة",
"اللغة العربية من أقدم اللغات السامية",
};

System.out.println("---");
for (String text : sentences) {
String out = diacrt.addDiacritics(text);
System.out.printf("Input: %s\n", text);
System.out.printf("Output: %s\n", out);
System.out.println("---");
}
}
}
37 changes: 37 additions & 0 deletions java-api-examples/run-offline-add-diacritics.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash

set -ex

if [[ ! -f ../build/lib/libsherpa-onnx-jni.dylib && ! -f ../build/lib/libsherpa-onnx-jni.so ]]; then
mkdir -p ../build
pushd ../build
cmake \
-DSHERPA_ONNX_ENABLE_PYTHON=OFF \
-DSHERPA_ONNX_ENABLE_TESTS=OFF \
-DSHERPA_ONNX_ENABLE_CHECK=OFF \
-DBUILD_SHARED_LIBS=ON \
-DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
-DSHERPA_ONNX_ENABLE_JNI=ON \
..

make -j4
ls -lh lib
popd
fi

if [ ! -f ../sherpa-onnx/java-api/build/sherpa-onnx.jar ]; then
pushd ../sherpa-onnx/java-api
make
popd
fi

if [[ ! -f "./catt_eo_model_onnx/encoder.onnx" || ! -f "./catt_eo_model_onnx/decoder.onnx" ]]; then
curl -SL -O https://github.com/abjadai/catt/releases/download/v2/eo_model_onnx.zip
unzip eo_model_onnx.zip -d catt_eo_model_onnx
rm eo_model_onnx.zip
fi

java \
-Djava.library.path=$PWD/../build/lib \
Comment thread
matiaslin marked this conversation as resolved.
-cp ../sherpa-onnx/java-api/build/sherpa-onnx.jar \
./OfflineAddDiacritics.java
4 changes: 4 additions & 0 deletions sherpa-onnx/java-api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ java_files += OfflineSpeechDenoiser.java
java_files += OnlineSpeechDenoiserConfig.java
java_files += OnlineSpeechDenoiser.java

java_files += OfflineDiacritizationModelConfig.java
java_files += OfflineDiacritizationConfig.java
java_files += OfflineDiacritization.java

class_files := $(java_files:%.java=%.class)

java_files := $(addprefix src/main/java/$(package_dir)/,$(java_files))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2026 Matias Lin

package com.k2fsa.sherpa.onnx;

public class OfflineDiacritization {
Comment thread
matiaslin marked this conversation as resolved.
private long ptr = 0;

public OfflineDiacritization(OfflineDiacritizationConfig config) {
LibraryLoader.maybeLoad();
ptr = newFromFile(config);
if (ptr == 0) {
throw new IllegalArgumentException("Invalid OfflineDiacritizationConfig: failed to create native OfflineDiacritization");
}
}
Comment thread
matiaslin marked this conversation as resolved.

public String addDiacritics(String text) {
return addDiacritics(ptr, text);
}
Comment thread
matiaslin marked this conversation as resolved.

@Override
protected void finalize() throws Throwable {
release();
}

// You'd better call it manually if it is not used anymore
Comment thread
matiaslin marked this conversation as resolved.
public void release() {
if (this.ptr == 0) {
return;
}
delete(this.ptr);
this.ptr = 0;
}
Comment thread
matiaslin marked this conversation as resolved.

private native void delete(long ptr);

private native long newFromFile(OfflineDiacritizationConfig config);

private native String addDiacritics(long ptr, String text);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2026 Matias Lin

package com.k2fsa.sherpa.onnx;

public class OfflineDiacritizationConfig {
private final OfflineDiacritizationModelConfig model;

private OfflineDiacritizationConfig(Builder builder) {
this.model = builder.model;
}

public static Builder builder() {
return new Builder();
}

public OfflineDiacritizationModelConfig getModel() {
return model;
}

public static class Builder {
private OfflineDiacritizationModelConfig model = OfflineDiacritizationModelConfig.builder().build();

public OfflineDiacritizationConfig build() {
return new OfflineDiacritizationConfig(this);
}

public Builder setModel(OfflineDiacritizationModelConfig model) {
this.model = model;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2026 Matias Lin

package com.k2fsa.sherpa.onnx;

public class OfflineDiacritizationModelConfig {
private final String cattEncoder;
private final String cattDecoder;
private final int numThreads;
private final boolean debug;
private final String provider;

private OfflineDiacritizationModelConfig(Builder builder) {
this.cattEncoder = builder.cattEncoder;
this.cattDecoder = builder.cattDecoder;
this.numThreads = builder.numThreads;
this.debug = builder.debug;
this.provider = builder.provider;
}

public static Builder builder() {
return new Builder();
}

public String getCattEncoder() {
return cattEncoder;
}

public String getCattDecoder() {
return cattDecoder;
}
Comment thread
matiaslin marked this conversation as resolved.

public static class Builder {
private String cattEncoder = "";
private String cattDecoder = "";
private int numThreads = 1;
private boolean debug = true;
private String provider = "cpu";

public OfflineDiacritizationModelConfig build() {
return new OfflineDiacritizationModelConfig(this);
}

public Builder setCattEncoder(String cattEncoder) {
this.cattEncoder = cattEncoder;
return this;
}

public Builder setCattDecoder(String cattDecoder) {
this.cattDecoder = cattDecoder;
return this;
}

public Builder setNumThreads(int numThreads) {
this.numThreads = numThreads;
return this;
}

public Builder setDebug(boolean debug) {
this.debug = debug;
return this;
}

public Builder setProvider(String provider) {
this.provider = provider;
return this;
}
}
}
1 change: 1 addition & 0 deletions sherpa-onnx/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(sources
common.cc
jni.cc
keyword-spotter.cc
offline-diacritization.cc
offline-punctuation.cc
offline-recognizer.cc
offline-speech-denoiser.cc
Expand Down
124 changes: 124 additions & 0 deletions sherpa-onnx/jni/offline-diacritization.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// sherpa-onnx/jni/offline-diacritization.cc
//
// Copyright (c) 2026 Matias Lin

#include "sherpa-onnx/csrc/offline-diacritization.h"

#include <string>

#include "sherpa-onnx/csrc/macros.h"
#include "sherpa-onnx/jni/common.h"

namespace sherpa_onnx {

static OfflineDiacritizationConfig GetOfflineDiacritizationConfig(
JNIEnv *env, jobject config, bool *ok) {
OfflineDiacritizationConfig ans;

jclass cls = env->GetObjectClass(config);
jfieldID fid;

fid = env->GetFieldID(
cls, "model", "Lcom/k2fsa/sherpa/onnx/OfflineDiacritizationModelConfig;");
jobject model_config = env->GetObjectField(config, fid);
jclass model_config_cls = env->GetObjectClass(model_config);
Comment thread
matiaslin marked this conversation as resolved.

Comment thread
matiaslin marked this conversation as resolved.
SHERPA_ONNX_JNI_READ_STRING(ans.model.catt_encoder, cattEncoder,
model_config_cls, model_config);

SHERPA_ONNX_JNI_READ_STRING(ans.model.catt_decoder, cattDecoder,
model_config_cls, model_config);

SHERPA_ONNX_JNI_READ_INT(ans.model.num_threads, numThreads, model_config_cls,
model_config);

SHERPA_ONNX_JNI_READ_BOOL(ans.model.debug, debug, model_config_cls,
model_config);

SHERPA_ONNX_JNI_READ_STRING(ans.model.provider, provider, model_config_cls,
model_config);

*ok = true;
return ans;
}

} // namespace sherpa_onnx

SHERPA_ONNX_EXTERN_C
JNIEXPORT jlong JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_newFromAsset(
JNIEnv *env, jobject /*obj*/, jobject asset_manager, jobject _config) {
#if __ANDROID_API__ >= 9
AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager);
if (!mgr) {
SHERPA_ONNX_LOGE("Failed to get asset manager: %p", mgr);
return 0;
}
#endif
bool ok = false;
auto config = sherpa_onnx::GetOfflineDiacritizationConfig(env, _config, &ok);

if (!ok) {
SHERPA_ONNX_LOGE("Please read the error message carefully");
return 0;
}

SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str());

auto model = new sherpa_onnx::OfflineDiacritization(
#if __ANDROID_API__ >= 9
mgr,
#endif
config);

return (jlong)model;
}

SHERPA_ONNX_EXTERN_C
JNIEXPORT jlong JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_newFromFile(JNIEnv *env,
jobject /*obj*/,
jobject _config) {
bool ok = false;
auto config = sherpa_onnx::GetOfflineDiacritizationConfig(env, _config, &ok);

if (!ok) {
SHERPA_ONNX_LOGE("Please read the error message carefully");
return 0;
}

SHERPA_ONNX_LOGE("config:\n%s", config.ToString().c_str());

if (!config.Validate()) {
SHERPA_ONNX_LOGE("Errors found in config!");
return 0;
}

auto model = new sherpa_onnx::OfflineDiacritization(config);

return (jlong)model;
}

SHERPA_ONNX_EXTERN_C
JNIEXPORT void JNICALL Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_delete(
JNIEnv * /*env*/, jobject /*obj*/, jlong ptr) {
delete reinterpret_cast<sherpa_onnx::OfflineDiacritization *>(ptr);
}

SHERPA_ONNX_EXTERN_C
JNIEXPORT jstring JNICALL
Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_addDiacritics(JNIEnv *env,
jobject /*obj*/,
jlong ptr,
jstring text) {
auto diacrt =
reinterpret_cast<const sherpa_onnx::OfflineDiacritization *>(ptr);

const char *ptext = env->GetStringUTFChars(text, nullptr);
Comment thread
matiaslin marked this conversation as resolved.

std::string result = diacrt->AddDiacritics(ptext);

env->ReleaseStringUTFChars(text, ptext);

return SafeNewStringUTF(env, result);
}
Comment thread
matiaslin marked this conversation as resolved.
4 changes: 4 additions & 0 deletions sherpa-onnx/jni/sherpa-onnx-symbols.exp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ _Java_com_k2fsa_sherpa_onnx_KeywordSpotter_isReady
_Java_com_k2fsa_sherpa_onnx_KeywordSpotter_newFromAsset
_Java_com_k2fsa_sherpa_onnx_KeywordSpotter_newFromFile
_Java_com_k2fsa_sherpa_onnx_KeywordSpotter_reset
_Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_addDiacritics
_Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_delete
_Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_newFromAsset
_Java_com_k2fsa_sherpa_onnx_OfflineDiacritization_newFromFile
_Java_com_k2fsa_sherpa_onnx_OfflinePunctuation_addPunctuation
_Java_com_k2fsa_sherpa_onnx_OfflinePunctuation_delete
_Java_com_k2fsa_sherpa_onnx_OfflinePunctuation_newFromAsset
Expand Down