1 /*---------------------------------------------------------------------------* 2 * android_speech_srec_Recognizer.cpp * 3 * * 4 * Copyright 2007 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 21 #include <string.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <jni.h> 25 26 #define LOG_TAG "srec_jni" 27 #include "utils/Log.h" 28 29 #include "passert.h" 30 #include "ESR_CommandLine.h" 31 #include "ESR_Session.h" 32 #include "LCHAR.h" 33 #include "PFile.h" 34 #include "PFileSystem.h" 35 #include "PANSIFileSystem.h" 36 //#include "PMemoryFileSystem.h" 37 #include "plog.h" 38 #include "pmemory.h" 39 #include "ptypes.h" 40 #include "SR_Grammar.h" 41 #include "SR_Recognizer.h" 42 #include "SR_RecognizerImpl.h" 43 #include "SR_RecognizerResult.h" 44 #include "SR_Session.h" 45 #include "SR_Vocabulary.h" 46 #include "SR_AcousticState.h" 47 #include "SR_Nametag.h" 48 #include "PStackSize.h" 49 50 51 52 // 53 // helper function to throw an exception 54 // 55 static void JNU_ThrowByName(JNIEnv *env, const char* name, const char* msg) { 56 jclass cls = env->FindClass(name); 57 if (cls != NULL) { 58 env->ThrowNew(cls, msg); 59 } 60 env->DeleteLocalRef(cls); 61 } 62 63 static void unimplemented(JNIEnv* env) { 64 JNU_ThrowByName(env, "java/lang/IllegalStateException", "unimplemented!!!"); 65 } 66 67 static void checkEsrError(JNIEnv* env, ESR_ReturnCode esr_status) { 68 if (esr_status != ESR_SUCCESS) { 69 JNU_ThrowByName(env, "java/lang/IllegalStateException", ESR_rc2str(esr_status)); 70 } 71 } 72 73 74 /////////////////////////////////////////////////////////////////////////// 75 // PMem JNI implementations 76 /////////////////////////////////////////////////////////////////////////// 77 78 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_PMemInit 79 (JNIEnv *env, jclass clazz) { 80 checkEsrError(env, PMemInit()); 81 } 82 83 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_PMemShutdown 84 (JNIEnv *env, jclass clazz) { 85 checkEsrError(env, PMemShutdown()); 86 } 87 88 89 ////////////////////////////////////////////////////////////////////////// 90 // SR_Session JNI implementations 91 ////////////////////////////////////////////////////////////////////////// 92 93 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1SessionCreate 94 (JNIEnv *env, jclass clazz, jstring fileName) { 95 // TODO: check for fileName NPE 96 const char* fn = env->GetStringUTFChars(fileName, 0); 97 checkEsrError(env, SR_SessionCreate(fn)); // TODO: can I post this before freeing the string? 98 env->ReleaseStringUTFChars(fileName, fn); 99 } 100 101 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1SessionDestroy 102 (JNIEnv *env, jclass clazz) { 103 checkEsrError(env, SR_SessionDestroy()); 104 } 105 106 107 ////////////////////////////////////////////////////////////////////////// 108 // SR_Recognizer JNI implementations 109 ////////////////////////////////////////////////////////////////////////// 110 111 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerStart 112 (JNIEnv *env, jclass clazz, jlong recognizer) { 113 checkEsrError(env, SR_RecognizerStart((SR_Recognizer*)recognizer)); 114 } 115 116 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerStop 117 (JNIEnv *env, jclass clazz, jlong recognizer) { 118 checkEsrError(env, SR_RecognizerStop((SR_Recognizer*)recognizer)); 119 } 120 121 static JNIEXPORT jlong JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerCreate 122 (JNIEnv *env, jclass clazz) { 123 SR_Recognizer* recognizer = NULL; 124 // TODO: do we need to clean up the recognizer if this fails? 125 checkEsrError(env, SR_RecognizerCreate(&recognizer)); 126 return (jlong)recognizer; 127 } 128 129 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerDestroy 130 (JNIEnv *env, jclass clazz, jlong recognizer) { 131 checkEsrError(env, SR_RecognizerDestroy((SR_Recognizer*)recognizer)); 132 return; 133 } 134 135 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetup 136 (JNIEnv *env, jclass clazz, jlong recognizer) { 137 checkEsrError(env, SR_RecognizerSetup((SR_Recognizer*)recognizer)); 138 return; 139 } 140 141 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerUnsetup 142 (JNIEnv *env, jclass clazz, jlong recognizer) { 143 checkEsrError(env, SR_RecognizerUnsetup((SR_Recognizer*)recognizer)); 144 return; 145 } 146 147 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSetup 148 (JNIEnv *env, jclass clazz, jlong recognizer) { 149 ESR_BOOL rtn = ESR_FALSE; 150 checkEsrError(env, SR_RecognizerIsSetup((SR_Recognizer*)recognizer, &rtn)); 151 return rtn; 152 } 153 154 static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerGetParameter 155 (JNIEnv *env, jclass clazz, jlong recognizer, jstring key) { 156 unimplemented(env); 157 return 0; 158 } 159 160 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerGetSize_1tParameter 161 (JNIEnv *env, jclass clazz, jlong recognizer, jstring key) { 162 unimplemented(env); 163 return 0; 164 } 165 166 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerGetBoolParameter 167 (JNIEnv *env, jclass clazz, jlong recognizer, jstring key) { 168 unimplemented(env); 169 return JNI_FALSE; 170 } 171 172 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetParameter 173 (JNIEnv *env, jclass clazz, jlong recognizer, jstring key, jstring value) { 174 unimplemented(env); 175 return; 176 } 177 178 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetSize_1tParameter 179 (JNIEnv *env, jclass clazz, jlong recognizer, jstring key, jint value) { 180 unimplemented(env); 181 return; 182 } 183 184 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetBoolParameter 185 (JNIEnv *env, jclass clazz, jlong recognizer, jstring key , jboolean value) { 186 unimplemented(env); 187 return; 188 } 189 190 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetupRule 191 (JNIEnv *env, jclass clazz, jlong recognizer, jlong grammar, jstring ruleName) { 192 const char* rn = env->GetStringUTFChars(ruleName, 0); 193 checkEsrError(env, SR_RecognizerSetupRule((SR_Recognizer*)recognizer, (SR_Grammar*)grammar, rn)); 194 env->ReleaseStringUTFChars(ruleName, rn); 195 } 196 197 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerHasSetupRules 198 (JNIEnv *env, jclass clazz, jlong recognizer) { 199 ESR_BOOL rtn = ESR_FALSE; 200 checkEsrError(env, SR_RecognizerHasSetupRules((SR_Recognizer*)recognizer, &rtn)); 201 return rtn; 202 } 203 204 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerActivateRule 205 (JNIEnv *env, jclass clazz, jlong recognizer, jlong grammar, jstring ruleName, jint weight) { 206 const char* rn = env->GetStringUTFChars(ruleName, 0); 207 checkEsrError(env, SR_RecognizerActivateRule((SR_Recognizer*)recognizer, (SR_Grammar*)grammar, rn, weight)); 208 env->ReleaseStringUTFChars(ruleName, rn); 209 } 210 211 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateRule 212 (JNIEnv *env, jclass clazz, jlong recognizer, jlong grammar, jstring ruleName) { 213 const char* rn = env->GetStringUTFChars(ruleName, 0); 214 checkEsrError(env, SR_RecognizerDeactivateRule((SR_Recognizer*)recognizer, (SR_Grammar*)grammar, rn)); 215 env->ReleaseStringUTFChars(ruleName, rn); 216 } 217 218 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateAllRules 219 (JNIEnv *env, jclass clazz, jlong recognizer) { 220 checkEsrError(env, SR_RecognizerDeactivateAllRules((SR_Recognizer*)recognizer)); 221 } 222 223 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsActiveRule 224 (JNIEnv *env, jclass clazz, jlong recognizer, jlong grammar, jstring ruleName) { 225 ESR_BOOL rtn = ESR_FALSE; 226 const char* rn = env->GetStringUTFChars(ruleName, 0); 227 checkEsrError(env, SR_RecognizerIsActiveRule((SR_Recognizer*)recognizer, (SR_Grammar*)grammar, rn, &rtn)); 228 env->ReleaseStringUTFChars(ruleName, rn); 229 return rtn; 230 } 231 232 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerCheckGrammarConsistency 233 (JNIEnv *env, jclass clazz, jlong recognizer, jlong grammar) { 234 ESR_BOOL rtn = ESR_FALSE; 235 checkEsrError(env, SR_RecognizerCheckGrammarConsistency((SR_Recognizer*)recognizer, (SR_Grammar*)grammar, &rtn)); 236 return rtn; 237 } 238 239 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerPutAudio 240 (JNIEnv *env, jclass clazz, jlong recognizer, jbyteArray audio, jint offset, jint length, jboolean isLast) { 241 // set the length 242 jbyte buffer[1024]; 243 if (length > (int)sizeof(buffer)) length = sizeof(buffer); 244 size_t samples = length / sizeof(asr_int16_t); 245 length = samples * sizeof(asr_int16_t); 246 247 // fetch data from java 248 env->GetByteArrayRegion(audio, offset, length, buffer); 249 250 // put the samples into the recognizer 251 checkEsrError(env, SR_RecognizerPutAudio((SR_Recognizer*)recognizer, 252 (asr_int16_t*)buffer, &samples, isLast ? ESR_TRUE : ESR_FALSE)); 253 if (samples != length / sizeof(asr_int16_t)) { 254 checkEsrError(env, ESR_READ_ERROR); 255 return 0; 256 } 257 258 return samples * sizeof(asr_int16_t); 259 } 260 261 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerAdvance 262 (JNIEnv *env, jclass clazz, jlong recognizer) { 263 SR_RecognizerStatus status = SR_RECOGNIZER_EVENT_INVALID; 264 SR_RecognizerResultType type = SR_RECOGNIZER_RESULT_TYPE_INVALID; 265 SR_RecognizerResult* recognizerResult = NULL; 266 checkEsrError(env, SR_RecognizerAdvance((SR_Recognizer*)recognizer, &status, &type, &recognizerResult)); 267 return status; 268 } 269 270 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalClipping 271 (JNIEnv *env, jclass clazz, jlong recognizer) { 272 ESR_BOOL rtn = ESR_FALSE; 273 checkEsrError(env, SR_RecognizerIsSignalClipping((SR_Recognizer*)recognizer, &rtn)); 274 return rtn; 275 } 276 277 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalDCOffset 278 (JNIEnv *env, jclass clazz, jlong recognizer) { 279 ESR_BOOL rtn = ESR_FALSE; 280 checkEsrError(env, SR_RecognizerIsSignalDCOffset((SR_Recognizer*)recognizer, &rtn)); 281 return rtn; 282 } 283 284 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalNoisy 285 (JNIEnv *env, jclass clazz, jlong recognizer) { 286 ESR_BOOL rtn = ESR_FALSE; 287 checkEsrError(env, SR_RecognizerIsSignalNoisy((SR_Recognizer*)recognizer, &rtn)); 288 return rtn; 289 } 290 291 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooQuiet 292 (JNIEnv *env, jclass clazz, jlong recognizer) { 293 ESR_BOOL rtn = ESR_FALSE; 294 checkEsrError(env, SR_RecognizerIsSignalTooQuiet((SR_Recognizer*)recognizer, &rtn)); 295 return rtn; 296 } 297 298 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooFewSamples 299 (JNIEnv *env, jclass clazz, jlong recognizer) { 300 ESR_BOOL rtn = ESR_FALSE; 301 checkEsrError(env, SR_RecognizerIsSignalTooFewSamples((SR_Recognizer*)recognizer, &rtn)); 302 return rtn; 303 } 304 305 static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooManySamples 306 (JNIEnv *env, jclass clazz, jlong recognizer) { 307 ESR_BOOL rtn = ESR_FALSE; 308 checkEsrError(env, SR_RecognizerIsSignalTooManySamples((SR_Recognizer*)recognizer, &rtn)); 309 return rtn; 310 } 311 312 313 ////////////////////////////////////////////////////////////////////////// 314 // SR_AcousticState JNI implementations 315 ////////////////////////////////////////////////////////////////////////// 316 317 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1AcousticStateReset 318 (JNIEnv *env, jclass clazz, jlong recognizer) { 319 checkEsrError(env, SR_AcousticStateReset((SR_Recognizer*)recognizer)); 320 } 321 322 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1AcousticStateSet 323 (JNIEnv *env, jclass clazz, jlong recognizer, jstring state) { 324 const char* st = env->GetStringUTFChars(state, 0); 325 checkEsrError(env, SR_AcousticStateSet((SR_Recognizer*)recognizer, st)); 326 env->ReleaseStringUTFChars(state, st); 327 } 328 329 static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1AcousticStateGet 330 (JNIEnv *env, jclass clazz, jlong recognizer) { 331 char rtn[1000]; 332 size_t rtnLength = sizeof(rtn) - 1; 333 ESR_ReturnCode esr_status = SR_AcousticStateGet((SR_Recognizer*)recognizer, rtn, &rtnLength); 334 if (esr_status) { 335 checkEsrError(env, esr_status); 336 return NULL; 337 } 338 rtn[rtnLength] = 0; 339 return env->NewStringUTF(rtn); 340 } 341 342 343 ////////////////////////////////////////////////////////////////////////// 344 // SR_Grammar JNI implementations 345 ////////////////////////////////////////////////////////////////////////// 346 347 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarCompile 348 (JNIEnv *env, jclass clazz, jlong grammar) { 349 checkEsrError(env, SR_GrammarCompile((SR_Grammar*)grammar)); 350 } 351 352 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAddWordToSlot 353 (JNIEnv *env, jclass clazz, jlong grammar, jstring slot, jstring word, jstring pronunciation, jint weight, jstring tag) { 354 const char* sl = 0; 355 const char* wo = 0; 356 const char* pr = 0; 357 const char* ta = 0; 358 if ((sl = env->GetStringUTFChars(slot, 0)) && 359 (wo = env->GetStringUTFChars(word, 0)) && 360 (!pronunciation || (pr = env->GetStringUTFChars(pronunciation, 0))) && 361 (ta = env->GetStringUTFChars(tag, 0))) { 362 checkEsrError(env, SR_GrammarAddWordToSlot((SR_Grammar*)grammar, sl, wo, pr, weight, ta)); 363 } 364 if (ta) env->ReleaseStringUTFChars(tag, ta); 365 if (pr) env->ReleaseStringUTFChars(pronunciation, pr); 366 if (wo) env->ReleaseStringUTFChars(word, wo); 367 if (sl) env->ReleaseStringUTFChars(slot, sl); 368 } 369 370 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarResetAllSlots 371 (JNIEnv *env, jclass clazz, jlong grammar) { 372 checkEsrError(env, SR_GrammarResetAllSlots((SR_Grammar*)grammar)); 373 } 374 375 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSetupVocabulary 376 (JNIEnv *env, jclass clazz, jlong grammar, jlong vocabulary) { 377 checkEsrError(env, SR_GrammarSetupVocabulary((SR_Grammar*)grammar, (SR_Vocabulary*)vocabulary)); 378 } 379 380 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSetupRecognizer 381 (JNIEnv *env, jclass clazz, jlong grammar, jlong recognizer) { 382 checkEsrError(env, SR_GrammarSetupRecognizer((SR_Grammar*)grammar, (SR_Recognizer*)recognizer)); 383 } 384 385 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarUnsetupRecognizer 386 (JNIEnv *env, jclass clazz, jlong grammar) { 387 checkEsrError(env, SR_GrammarUnsetupRecognizer((SR_Grammar*)grammar)); 388 } 389 390 static JNIEXPORT jlong JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarCreate 391 (JNIEnv *env, jclass clazz) { 392 SR_Grammar* grammar = 0; 393 checkEsrError(env, SR_GrammarCreate(&grammar)); 394 return (jlong)grammar; 395 } 396 397 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarDestroy 398 (JNIEnv *env, jclass clazz, jlong grammar) { 399 checkEsrError(env, SR_GrammarDestroy((SR_Grammar*)grammar)); 400 } 401 402 static JNIEXPORT jlong JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarLoad 403 (JNIEnv *env, jclass clazz, jstring fileName) { 404 // TODO: check for fileName NPE 405 SR_Grammar* grammar = 0; 406 const char* fn = env->GetStringUTFChars(fileName, 0); 407 checkEsrError(env, SR_GrammarLoad(fn, &grammar)); 408 env->ReleaseStringUTFChars(fileName, fn); 409 return (jlong)grammar; 410 } 411 412 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSave 413 (JNIEnv *env, jclass clazz, jlong grammar, jstring fileName) { 414 const char* fn = env->GetStringUTFChars(fileName, 0); 415 checkEsrError(env, SR_GrammarSave((SR_Grammar*)grammar, fn)); 416 env->ReleaseStringUTFChars(fileName, fn); 417 } 418 419 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAllowOnly 420 (JNIEnv *env, jclass clazz, jlong grammar, jstring transcription) { 421 const char* tr = env->GetStringUTFChars(transcription, 0); 422 checkEsrError(env, SR_GrammarSave((SR_Grammar*)grammar, tr)); 423 env->ReleaseStringUTFChars(transcription, tr); 424 } 425 426 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAllowAll 427 (JNIEnv *env, jclass clazz, jlong grammar) { 428 checkEsrError(env, SR_GrammarAllowAll((SR_Grammar*)grammar)); 429 } 430 431 432 ////////////////////////////////////////////////////////////////////////// 433 // SR_Vocabulary JNI implementations 434 ////////////////////////////////////////////////////////////////////////// 435 436 static JNIEXPORT jlong JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyLoad 437 (JNIEnv *env, jclass clazz) { 438 char filename[P_PATH_MAX]; 439 size_t flen = sizeof(filename) - 1; 440 checkEsrError(env, ESR_SessionGetLCHAR ( L("cmdline.vocabulary"), filename, &flen )); 441 filename[sizeof(filename) - 1] = 0; 442 // TODO: do we need to clean up the recognizer if this fails? 443 SR_Vocabulary* vocabulary = NULL; 444 checkEsrError(env, SR_VocabularyLoad(filename, &vocabulary)); 445 return (jlong)vocabulary; 446 } 447 448 static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyDestroy 449 (JNIEnv *env, jclass clazz, jlong vocabulary) { 450 // TODO: do we need to clean up the recognizer if this fails? 451 checkEsrError(env, SR_VocabularyDestroy((SR_Vocabulary*)vocabulary)); 452 } 453 454 static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyGetPronunciation 455 (JNIEnv *env, jclass clazz, jlong vocabulary, jstring word) { 456 char rtn[1000]; 457 size_t rtnLength = sizeof(rtn) - 1; 458 const char* wo = env->GetStringUTFChars(word, 0); 459 ESR_ReturnCode esr_status = SR_VocabularyGetPronunciation((SR_Vocabulary*)vocabulary, wo, rtn, &rtnLength); 460 env->ReleaseStringUTFChars(word, wo); 461 if (esr_status) { 462 checkEsrError(env, esr_status); 463 return NULL; 464 } 465 rtn[rtnLength] = 0; 466 return env->NewStringUTF(rtn); 467 } 468 469 470 ////////////////////////////////////////////////////////////////////////// 471 // SR_RecognizerResult JNI implementations 472 ////////////////////////////////////////////////////////////////////////// 473 474 static JNIEXPORT jbyteArray JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetWaveform 475 (JNIEnv *env, jclass clazz, jlong recognizer) { 476 unimplemented(env); 477 return 0; 478 } 479 480 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetSize 481 (JNIEnv *env, jclass clazz, jlong recognizer) { 482 size_t size = 0; 483 checkEsrError(env, SR_RecognizerResultGetSize(((SR_RecognizerImpl*)recognizer)->result, &size)); 484 return size; 485 } 486 487 static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyCount 488 (JNIEnv *env, jclass clazz, jlong recognizer, jint nbest) { 489 size_t size = 0; 490 checkEsrError(env, SR_RecognizerResultGetKeyCount(((SR_RecognizerImpl*)recognizer)->result, nbest, &size)); 491 return size; 492 } 493 494 static JNIEXPORT jobjectArray JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyList 495 (JNIEnv *env, jclass clazz, jlong recognizer, jint nbest) { 496 // fetch list 497 LCHAR* list[200]; 498 size_t listSize = sizeof(list) / sizeof(list[0]); 499 ESR_ReturnCode esr_status = SR_RecognizerResultGetKeyList(((SR_RecognizerImpl*)recognizer)->result, nbest, list, &listSize); 500 if (esr_status) { 501 checkEsrError(env, esr_status); 502 return NULL; 503 } 504 505 // create String[] of keys 506 jclass stringClass = env->FindClass("java/lang/String"); 507 if (!stringClass) return NULL; 508 jobjectArray array = env->NewObjectArray(listSize, stringClass, NULL); 509 if (!array) return NULL; 510 511 // fill it 512 for (size_t i = 0; i < listSize; i++) { 513 // generate new String for key 514 jstring key = env->NewStringUTF(list[i]); 515 if (!key) return NULL; 516 // set the array 517 env->SetObjectArrayElement(array, i, key); 518 env->DeleteLocalRef(key); 519 } 520 521 return array; 522 } 523 524 static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetValue 525 (JNIEnv *env, jclass clazz, jlong recognizer, jint nbest, jstring key) { 526 char rtn[1000]; 527 size_t rtnLength = sizeof(rtn) - 1; 528 const char* ke = env->GetStringUTFChars(key, 0); 529 ESR_ReturnCode esr_status = SR_RecognizerResultGetValue(((SR_RecognizerImpl*)recognizer)->result, nbest, ke, rtn, &rtnLength); 530 env->ReleaseStringUTFChars(key, ke); 531 if (esr_status) { 532 checkEsrError(env, esr_status); 533 return NULL; 534 } 535 rtn[rtnLength] = 0; 536 return env->NewStringUTF(rtn); 537 } 538 539 540 /* 541 * Table of methods associated with a single class. 542 */ 543 static JNINativeMethod gMethods[] = { 544 /* name, signature, funcPtr */ 545 // PMem 546 {"PMemInit", "()V", (void*)Java_android_speech_srec_Recognizer_PMemInit}, 547 {"PMemShutdown", "()V", (void*)Java_android_speech_srec_Recognizer_PMemShutdown}, 548 // SR_Session 549 {"SR_SessionCreate", "(Ljava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1SessionCreate}, 550 {"SR_SessionDestroy", "()V", (void*)Java_android_speech_srec_Recognizer_SR_1SessionDestroy}, 551 // SR_Recognizer 552 {"SR_RecognizerStart", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerStart}, 553 {"SR_RecognizerStop", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerStop}, 554 {"SR_RecognizerCreate", "()J", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerCreate}, 555 {"SR_RecognizerDestroy", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDestroy}, 556 {"SR_RecognizerSetup", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetup}, 557 {"SR_RecognizerUnsetup", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerUnsetup}, 558 {"SR_RecognizerIsSetup", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSetup}, 559 {"SR_RecognizerGetParameter", "(JLjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetParameter}, 560 {"SR_RecognizerGetSize_tParameter", "(JLjava/lang/String;)I", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetSize_1tParameter}, 561 {"SR_RecognizerGetBoolParameter", "(JLjava/lang/String;)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetBoolParameter}, 562 {"SR_RecognizerSetParameter", "(JLjava/lang/String;Ljava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetParameter}, 563 {"SR_RecognizerSetSize_tParameter", "(JLjava/lang/String;I)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetSize_1tParameter}, 564 {"SR_RecognizerSetBoolParameter", "(JLjava/lang/String;Z)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetBoolParameter}, 565 {"SR_RecognizerSetupRule", "(JJLjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetupRule}, 566 {"SR_RecognizerHasSetupRules", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerHasSetupRules}, 567 {"SR_RecognizerActivateRule", "(JJLjava/lang/String;I)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerActivateRule}, 568 {"SR_RecognizerDeactivateRule", "(JJLjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateRule}, 569 {"SR_RecognizerDeactivateAllRules", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateAllRules}, 570 {"SR_RecognizerIsActiveRule", "(JJLjava/lang/String;)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsActiveRule}, 571 {"SR_RecognizerCheckGrammarConsistency", "(JJ)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerCheckGrammarConsistency}, 572 {"SR_RecognizerPutAudio", "(J[BIIZ)I", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerPutAudio}, 573 {"SR_RecognizerAdvance", "(J)I", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerAdvance}, 574 {"SR_RecognizerIsSignalClipping", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalClipping}, 575 {"SR_RecognizerIsSignalDCOffset", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalDCOffset}, 576 {"SR_RecognizerIsSignalNoisy", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalNoisy}, 577 {"SR_RecognizerIsSignalTooQuiet", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooQuiet}, 578 {"SR_RecognizerIsSignalTooFewSamples", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooFewSamples}, 579 {"SR_RecognizerIsSignalTooManySamples", "(J)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooManySamples}, 580 // SR_AcousticState 581 {"SR_AcousticStateReset", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1AcousticStateReset}, 582 {"SR_AcousticStateSet", "(JLjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1AcousticStateSet}, 583 {"SR_AcousticStateGet", "(J)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1AcousticStateGet}, 584 // SR_Grammar 585 {"SR_GrammarCompile", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarCompile}, 586 {"SR_GrammarAddWordToSlot", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAddWordToSlot}, 587 {"SR_GrammarResetAllSlots", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarResetAllSlots}, 588 {"SR_GrammarSetupVocabulary", "(JJ)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSetupVocabulary}, 589 {"SR_GrammarSetupRecognizer", "(JJ)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSetupRecognizer}, 590 {"SR_GrammarUnsetupRecognizer", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarUnsetupRecognizer}, 591 {"SR_GrammarCreate", "()J", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarCreate}, 592 {"SR_GrammarDestroy", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarDestroy}, 593 {"SR_GrammarLoad", "(Ljava/lang/String;)J", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarLoad}, 594 {"SR_GrammarSave", "(JLjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSave}, 595 {"SR_GrammarAllowOnly", "(JLjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAllowOnly}, 596 {"SR_GrammarAllowAll", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAllowAll}, 597 // SR_Vocabulary 598 {"SR_VocabularyLoad", "()J", (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyLoad}, 599 {"SR_VocabularyDestroy", "(J)V", (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyDestroy}, 600 {"SR_VocabularyGetPronunciation", "(JLjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyGetPronunciation}, 601 // SR_RecognizerResult 602 {"SR_RecognizerResultGetWaveform", "(J)[B", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetWaveform}, 603 {"SR_RecognizerResultGetSize", "(J)I", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetSize}, 604 {"SR_RecognizerResultGetKeyCount", "(JI)I", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyCount}, 605 {"SR_RecognizerResultGetKeyList", "(JI)[Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyList}, 606 {"SR_RecognizerResultGetValue", "(JILjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetValue}, 607 }; 608 609 /* 610 * Returns the JNI version on success, -1 on failure. 611 */ 612 jint register_android_speech_srec_Recognizer(JavaVM* vm, void* reserved) 613 { 614 JNIEnv* env = NULL; 615 jclass clazz = NULL; 616 const char* className = "android/speech/srec/Recognizer"; 617 618 if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 619 ALOGE("ERROR: GetEnv failed\n"); 620 return -1; 621 } 622 assert(env != NULL); 623 624 clazz = env->FindClass(className); 625 if (clazz == NULL) { 626 ALOGE("Native registration unable to find class '%s'\n", className); 627 return -1; 628 } 629 if (env->RegisterNatives(clazz, gMethods, 630 sizeof(gMethods) / sizeof(gMethods[0])) < 0) { 631 ALOGE("RegisterNatives failed for '%s'\n", className); 632 return -1; 633 } 634 635 /* success -- return valid version number */ 636 return JNI_VERSION_1_4; 637 } 638 639 640 extern jint register_android_speech_srec_MicrophoneInputStream(JavaVM* vm, void* reserved); 641 642 jint JNI_OnLoad(JavaVM* vm, void* reserved) 643 { 644 if (register_android_speech_srec_MicrophoneInputStream(vm, reserved) != JNI_VERSION_1_4 || 645 register_android_speech_srec_Recognizer(vm, reserved) != JNI_VERSION_1_4) return -1; 646 return JNI_VERSION_1_4; 647 } 648