Skip to content

Commit 26a55b1

Browse files
authored
Small fixes to JNI wrappers (k2-fsa#3298)
1 parent a629912 commit 26a55b1

15 files changed

Lines changed: 186 additions & 104 deletions

java-api-examples/OfflineSpeakerDiarizationDemo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public static void main(String[] args) {
7373
if (sd.getSampleRate() != reader.getSampleRate()) {
7474
System.out.printf(
7575
"Expected sample rate: %d, given: %d\n", sd.getSampleRate(), reader.getSampleRate());
76+
sd.release();
7677
return;
7778
}
7879

java-api-examples/SpeakerIdentification.java

Lines changed: 84 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -31,102 +31,104 @@ public static void main(String[] args) {
3131
SpeakerEmbeddingExtractor extractor = new SpeakerEmbeddingExtractor(config);
3232
SpeakerEmbeddingManager manager = new SpeakerEmbeddingManager(extractor.getDim());
3333

34-
String[] spk1Files =
35-
new String[] {
36-
"./sr-data/enroll/fangjun-sr-1.wav",
37-
"./sr-data/enroll/fangjun-sr-2.wav",
38-
"./sr-data/enroll/fangjun-sr-3.wav",
39-
};
40-
41-
float[][] spk1Vec = new float[spk1Files.length][];
42-
43-
for (int i = 0; i < spk1Files.length; ++i) {
44-
spk1Vec[i] = computeEmbedding(extractor, spk1Files[i]);
45-
}
34+
try {
35+
String[] spk1Files =
36+
new String[] {
37+
"./sr-data/enroll/fangjun-sr-1.wav",
38+
"./sr-data/enroll/fangjun-sr-2.wav",
39+
"./sr-data/enroll/fangjun-sr-3.wav",
40+
};
41+
42+
float[][] spk1Vec = new float[spk1Files.length][];
43+
44+
for (int i = 0; i < spk1Files.length; ++i) {
45+
spk1Vec[i] = computeEmbedding(extractor, spk1Files[i]);
46+
}
4647

47-
String[] spk2Files =
48-
new String[] {
49-
"./sr-data/enroll/leijun-sr-1.wav", "./sr-data/enroll/leijun-sr-2.wav",
50-
};
48+
String[] spk2Files =
49+
new String[] {
50+
"./sr-data/enroll/leijun-sr-1.wav", "./sr-data/enroll/leijun-sr-2.wav",
51+
};
5152

52-
float[][] spk2Vec = new float[spk2Files.length][];
53+
float[][] spk2Vec = new float[spk2Files.length][];
5354

54-
for (int i = 0; i < spk2Files.length; ++i) {
55-
spk2Vec[i] = computeEmbedding(extractor, spk2Files[i]);
56-
}
55+
for (int i = 0; i < spk2Files.length; ++i) {
56+
spk2Vec[i] = computeEmbedding(extractor, spk2Files[i]);
57+
}
5758

58-
if (!manager.add("fangjun", spk1Vec)) {
59-
System.out.println("Failed to register fangjun");
60-
return;
61-
}
59+
if (!manager.add("fangjun", spk1Vec)) {
60+
System.out.println("Failed to register fangjun");
61+
return;
62+
}
6263

63-
if (!manager.add("leijun", spk2Vec)) {
64-
System.out.println("Failed to register leijun");
65-
return;
66-
}
64+
if (!manager.add("leijun", spk2Vec)) {
65+
System.out.println("Failed to register leijun");
66+
return;
67+
}
6768

68-
if (manager.getNumSpeakers() != 2) {
69-
System.out.println("There should be two speakers");
70-
return;
71-
}
69+
if (manager.getNumSpeakers() != 2) {
70+
System.out.println("There should be two speakers");
71+
return;
72+
}
7273

73-
if (!manager.contains("fangjun")) {
74-
System.out.println("It should contain the speaker fangjun");
75-
return;
76-
}
74+
if (!manager.contains("fangjun")) {
75+
System.out.println("It should contain the speaker fangjun");
76+
return;
77+
}
7778

78-
if (!manager.contains("leijun")) {
79-
System.out.println("It should contain the speaker leijun");
80-
return;
81-
}
79+
if (!manager.contains("leijun")) {
80+
System.out.println("It should contain the speaker leijun");
81+
return;
82+
}
8283

83-
System.out.println("---All speakers---");
84-
String[] allSpeakers = manager.getAllSpeakerNames();
85-
for (String s : allSpeakers) {
86-
System.out.println(s);
87-
}
88-
System.out.println("------------");
89-
90-
String[] testFiles =
91-
new String[] {
92-
"./sr-data/test/fangjun-test-sr-1.wav",
93-
"./sr-data/test/leijun-test-sr-1.wav",
94-
"./sr-data/test/liudehua-test-sr-1.wav"
95-
};
96-
97-
float threshold = 0.6f;
98-
for (String file : testFiles) {
99-
float[] embedding = computeEmbedding(extractor, file);
100-
101-
String name = manager.search(embedding, threshold);
102-
if (name.isEmpty()) {
103-
name = "<Unknown>";
84+
System.out.println("---All speakers---");
85+
String[] allSpeakers = manager.getAllSpeakerNames();
86+
for (String s : allSpeakers) {
87+
System.out.println(s);
88+
}
89+
System.out.println("------------");
90+
91+
String[] testFiles =
92+
new String[] {
93+
"./sr-data/test/fangjun-test-sr-1.wav",
94+
"./sr-data/test/leijun-test-sr-1.wav",
95+
"./sr-data/test/liudehua-test-sr-1.wav"
96+
};
97+
98+
float threshold = 0.6f;
99+
for (String file : testFiles) {
100+
float[] embedding = computeEmbedding(extractor, file);
101+
102+
String name = manager.search(embedding, threshold);
103+
if (name.isEmpty()) {
104+
name = "<Unknown>";
105+
}
106+
System.out.printf("%s: %s\n", file, name);
104107
}
105-
System.out.printf("%s: %s\n", file, name);
106-
}
107108

108-
// test verify
109-
if (!manager.verify("fangjun", computeEmbedding(extractor, testFiles[0]), threshold)) {
110-
System.out.printf("%s should match fangjun!\n", testFiles[0]);
111-
return;
112-
}
109+
// test verify
110+
if (!manager.verify("fangjun", computeEmbedding(extractor, testFiles[0]), threshold)) {
111+
System.out.printf("%s should match fangjun!\n", testFiles[0]);
112+
return;
113+
}
113114

114-
if (!manager.remove("fangjun")) {
115-
System.out.println("Failed to remove fangjun");
116-
return;
117-
}
115+
if (!manager.remove("fangjun")) {
116+
System.out.println("Failed to remove fangjun");
117+
return;
118+
}
118119

119-
if (manager.verify("fangjun", computeEmbedding(extractor, testFiles[0]), threshold)) {
120-
System.out.printf("%s should match no one!\n", testFiles[0]);
121-
return;
122-
}
120+
if (manager.verify("fangjun", computeEmbedding(extractor, testFiles[0]), threshold)) {
121+
System.out.printf("%s should match no one!\n", testFiles[0]);
122+
return;
123+
}
123124

124-
if (manager.getNumSpeakers() != 1) {
125-
System.out.println("There should only 1 speaker left.");
126-
return;
125+
if (manager.getNumSpeakers() != 1) {
126+
System.out.println("There should only 1 speaker left.");
127+
return;
128+
}
129+
} finally {
130+
extractor.release();
131+
manager.release();
127132
}
128-
129-
extractor.release();
130-
manager.release();
131133
}
132134
}

sherpa-onnx/jni/audio-tagging.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_k2fsa_sherpa_onnx_AudioTagging_compute(
144144
jmethodID ctor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;IF)V");
145145
if (ctor == nullptr) {
146146
SHERPA_ONNX_LOGE("Failed to get AudioEvent constructor");
147+
env->DeleteLocalRef(cls);
147148
return nullptr;
148149
}
149150

sherpa-onnx/jni/jni.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
jobject NewInteger(JNIEnv *env, int32_t value) {
1818
jclass cls = env->FindClass("java/lang/Integer");
1919
jmethodID constructor = env->GetMethodID(cls, "<init>", "(I)V");
20-
return env->NewObject(cls, constructor, value);
20+
jobject obj = env->NewObject(cls, constructor, value);
21+
env->DeleteLocalRef(cls);
22+
return obj;
2123
}
2224

2325
jobject NewFloat(JNIEnv *env, float value) {
2426
jclass cls = env->FindClass("java/lang/Float");
2527
jmethodID constructor = env->GetMethodID(cls, "<init>", "(F)V");
26-
return env->NewObject(cls, constructor, value);
28+
jobject obj = env->NewObject(cls, constructor, value);
29+
env->DeleteLocalRef(cls);
30+
return obj;
2731
}

sherpa-onnx/jni/keyword-spotter.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_KeywordSpotter_createStream(
173173
}
174174

175175
SHERPA_ONNX_EXTERN_C
176-
JNIEXPORT bool JNICALL Java_com_k2fsa_sherpa_onnx_KeywordSpotter_isReady(
176+
JNIEXPORT jboolean JNICALL Java_com_k2fsa_sherpa_onnx_KeywordSpotter_isReady(
177177
JNIEnv * /*env*/, jobject /*obj*/, jlong ptr, jlong stream_ptr) {
178178
auto kws = reinterpret_cast<sherpa_onnx::KeywordSpotter *>(ptr);
179179
auto stream = reinterpret_cast<sherpa_onnx::OnlineStream *>(stream_ptr);
@@ -195,6 +195,7 @@ JNIEXPORT jobject JNICALL Java_com_k2fsa_sherpa_onnx_KeywordSpotter_getResult(
195195
jclass string_cls = env->FindClass("java/lang/String");
196196
if (string_cls == nullptr) {
197197
SHERPA_ONNX_LOGE("Failed to find class java/lang/String");
198+
env->DeleteLocalRef(j_keyword);
198199
return nullptr;
199200
}
200201

@@ -219,6 +220,10 @@ JNIEXPORT jobject JNICALL Java_com_k2fsa_sherpa_onnx_KeywordSpotter_getResult(
219220
if (result_cls == nullptr) {
220221
SHERPA_ONNX_LOGE(
221222
"Failed to find class com/k2fsa/sherpa/onnx/KeywordSpotterResult");
223+
env->DeleteLocalRef(j_keyword);
224+
env->DeleteLocalRef(j_tokens);
225+
env->DeleteLocalRef(j_timestamps);
226+
env->DeleteLocalRef(string_cls);
222227
return nullptr;
223228
}
224229

@@ -227,6 +232,11 @@ JNIEXPORT jobject JNICALL Java_com_k2fsa_sherpa_onnx_KeywordSpotter_getResult(
227232

228233
if (ctor == nullptr) {
229234
SHERPA_ONNX_LOGE("Failed to get KeywordSpotterResult constructor");
235+
env->DeleteLocalRef(j_keyword);
236+
env->DeleteLocalRef(j_tokens);
237+
env->DeleteLocalRef(j_timestamps);
238+
env->DeleteLocalRef(result_cls);
239+
env->DeleteLocalRef(string_cls);
230240
return nullptr;
231241
}
232242

sherpa-onnx/jni/offline-recognizer.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,14 +557,20 @@ Java_com_k2fsa_sherpa_onnx_OfflineRecognizer_getResult(JNIEnv *env,
557557

558558
// 2. Find the Java class and constructor
559559
jclass cls = env->FindClass("com/k2fsa/sherpa/onnx/OfflineRecognizerResult");
560+
if (cls == nullptr) {
561+
SHERPA_ONNX_LOGE("Failed to find class OfflineRecognizerResult");
562+
return nullptr;
563+
}
560564
jmethodID ctor =
561565
env->GetMethodID(cls, "<init>",
562566
"(Ljava/lang/String;[Ljava/lang/String;[FLjava/lang/"
563567
"String;Ljava/lang/String;Ljava/lang/String;[F)V");
564568
jstring jtext = env->NewStringUTF(result.text.c_str());
565569

570+
jclass string_cls = env->FindClass("java/lang/String");
566571
jobjectArray jtokens = env->NewObjectArray(
567-
result.tokens.size(), env->FindClass("java/lang/String"), nullptr);
572+
result.tokens.size(), string_cls, nullptr);
573+
env->DeleteLocalRef(string_cls);
568574

569575
for (size_t i = 0; i < result.tokens.size(); ++i) {
570576
jstring token_str = env->NewStringUTF(result.tokens[i].c_str());

sherpa-onnx/jni/offline-speaker-diarization.cc

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,19 +173,32 @@ static jobjectArray ProcessImpl(
173173
&segments) {
174174
jclass cls =
175175
env->FindClass("com/k2fsa/sherpa/onnx/OfflineSpeakerDiarizationSegment");
176+
if (cls == nullptr) {
177+
SHERPA_ONNX_LOGE(
178+
"Failed to find class OfflineSpeakerDiarizationSegment");
179+
return nullptr;
180+
}
176181

177182
jobjectArray obj_arr =
178183
(jobjectArray)env->NewObjectArray(segments.size(), cls, nullptr);
179184

180185
jmethodID constructor = env->GetMethodID(cls, "<init>", "(FFI)V");
186+
if (constructor == nullptr) {
187+
SHERPA_ONNX_LOGE(
188+
"Failed to get OfflineSpeakerDiarizationSegment constructor");
189+
env->DeleteLocalRef(cls);
190+
return nullptr;
191+
}
181192

182-
for (int32_t i = 0; i != segments.size(); ++i) {
193+
for (int32_t i = 0; i != static_cast<int32_t>(segments.size()); ++i) {
183194
const auto &s = segments[i];
184195
jobject segment =
185196
env->NewObject(cls, constructor, s.Start(), s.End(), s.Speaker());
186197
env->SetObjectArrayElement(obj_arr, i, segment);
198+
env->DeleteLocalRef(segment);
187199
}
188200

201+
env->DeleteLocalRef(cls);
189202
return obj_arr;
190203
}
191204

@@ -216,14 +229,23 @@ Java_com_k2fsa_sherpa_onnx_OfflineSpeakerDiarization_processWithCallback(
216229
jmethodID mid = env->GetMethodID(cls, "invoke", "(IIJ)Ljava/lang/Integer;");
217230
if (mid == nullptr) {
218231
SHERPA_ONNX_LOGE("Failed to get the callback. Ignore it.");
232+
env->DeleteLocalRef(cls);
219233
return 0;
220234
}
235+
env->DeleteLocalRef(cls);
221236

222237
jobject ret = env->CallObjectMethod(callback, mid, num_processed_chunks,
223238
num_total_chunks, (jlong)data);
239+
if (ret == nullptr) {
240+
return 0;
241+
}
242+
224243
jclass jklass = env->GetObjectClass(ret);
225244
jmethodID int_value_mid = env->GetMethodID(jklass, "intValue", "()I");
226-
return env->CallIntMethod(ret, int_value_mid);
245+
int32_t result = env->CallIntMethod(ret, int_value_mid);
246+
env->DeleteLocalRef(jklass);
247+
env->DeleteLocalRef(ret);
248+
return result;
227249
};
228250

229251
auto sd = reinterpret_cast<sherpa_onnx::OfflineSpeakerDiarization *>(ptr);

sherpa-onnx/jni/offline-speech-denoiser.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,21 @@ JNIEXPORT jobject JNICALL Java_com_k2fsa_sherpa_onnx_OfflineSpeechDenoiser_run(
135135
return nullptr;
136136
}
137137

138-
// https://javap.yawk.at/
139138
jmethodID constructor = env->GetMethodID(cls, "<init>", "([FI)V");
140139
if (constructor == nullptr) {
141140
SHERPA_ONNX_LOGE("Failed to get constructor for DenoisedAudio");
141+
env->DeleteLocalRef(cls);
142142
return nullptr;
143143
}
144144

145145
jfloatArray samples_arr = env->NewFloatArray(denoised.samples.size());
146146
env->SetFloatArrayRegion(samples_arr, 0, denoised.samples.size(),
147147
denoised.samples.data());
148148

149-
return env->NewObject(cls, constructor, samples_arr, denoised.sample_rate);
149+
jobject obj = env->NewObject(cls, constructor, samples_arr, denoised.sample_rate);
150+
env->DeleteLocalRef(cls);
151+
env->DeleteLocalRef(samples_arr);
152+
return obj;
150153
}
151154

152155
SHERPA_ONNX_EXTERN_C

sherpa-onnx/jni/offline-tts.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ JNIEXPORT jlong JNICALL Java_com_k2fsa_sherpa_onnx_OfflineTts_newFromFile(
440440

441441
if (!config.Validate()) {
442442
SHERPA_ONNX_LOGE("Errors found in config!");
443+
return 0;
443444
}
444445

445446
auto tts = new sherpa_onnx::OfflineTts(config);

0 commit comments

Comments
 (0)