android_speech_srec_Recognizer.cpp revision 14c27f8650c090a4bab4ab4156f335c762ab228a
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//
55static 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
63static void unimplemented(JNIEnv* env) {
64    JNU_ThrowByName(env, "java/lang/IllegalStateException", "unimplemented!!!");
65}
66
67static 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
78static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_PMemInit
79        (JNIEnv *env, jclass clazz) {
80    checkEsrError(env, PMemInit());
81}
82
83static 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
93static 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
101static 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
111static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerStart
112        (JNIEnv *env, jclass clazz, jint recognizer) {
113    checkEsrError(env, SR_RecognizerStart((SR_Recognizer*)recognizer));
114}
115
116static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerStop
117        (JNIEnv *env, jclass clazz, jint recognizer) {
118    checkEsrError(env, SR_RecognizerStop((SR_Recognizer*)recognizer));
119}
120
121static JNIEXPORT jint 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 (jint)recognizer;
127}
128
129static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerDestroy
130        (JNIEnv *env, jclass clazz, jint recognizer) {
131    checkEsrError(env, SR_RecognizerDestroy((SR_Recognizer*)recognizer));
132    return;
133}
134
135static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetup
136        (JNIEnv *env, jclass clazz, jint recognizer) {
137    checkEsrError(env, SR_RecognizerSetup((SR_Recognizer*)recognizer));
138    return;
139}
140
141static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerUnsetup
142        (JNIEnv *env, jclass clazz, jint recognizer) {
143    checkEsrError(env, SR_RecognizerUnsetup((SR_Recognizer*)recognizer));
144    return;
145}
146
147static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSetup
148        (JNIEnv *env, jclass clazz, jint recognizer) {
149    ESR_BOOL rtn = ESR_FALSE;
150    checkEsrError(env, SR_RecognizerIsSetup((SR_Recognizer*)recognizer, &rtn));
151    return rtn;
152}
153
154static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerGetParameter
155  (JNIEnv *env, jclass clazz, jint recognizer, jstring key) {
156    unimplemented(env);
157    return 0;
158}
159
160static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerGetSize_1tParameter
161  (JNIEnv *env, jclass clazz, jint recognizer, jstring key) {
162    unimplemented(env);
163    return 0;
164}
165
166static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerGetBoolParameter
167  (JNIEnv *env, jclass clazz, jint recognizer, jstring key) {
168    unimplemented(env);
169    return JNI_FALSE;
170}
171
172static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetParameter
173  (JNIEnv *env, jclass clazz, jint recognizer, jstring key, jstring value) {
174    unimplemented(env);
175    return;
176}
177
178static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetSize_1tParameter
179  (JNIEnv *env, jclass clazz, jint recognizer, jstring key, jint value) {
180    unimplemented(env);
181    return;
182}
183
184static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetBoolParameter
185  (JNIEnv *env, jclass clazz, jint recognizer, jstring key , jboolean value) {
186    unimplemented(env);
187    return;
188}
189
190static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerSetupRule
191        (JNIEnv *env, jclass clazz, jint recognizer, jint 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
197static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerHasSetupRules
198        (JNIEnv *env, jclass clazz, jint recognizer) {
199    ESR_BOOL rtn = ESR_FALSE;
200    checkEsrError(env, SR_RecognizerHasSetupRules((SR_Recognizer*)recognizer, &rtn));
201    return rtn;
202}
203
204static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerActivateRule
205        (JNIEnv *env, jclass clazz, jint recognizer, jint 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
211static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateRule
212        (JNIEnv *env, jclass clazz, jint recognizer, jint 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
218static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateAllRules
219        (JNIEnv *env, jclass clazz, jint recognizer) {
220    checkEsrError(env, SR_RecognizerDeactivateAllRules((SR_Recognizer*)recognizer));
221}
222
223static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsActiveRule
224        (JNIEnv *env, jclass clazz, jint recognizer, jint 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
232static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerCheckGrammarConsistency
233        (JNIEnv *env, jclass clazz, jint recognizer, jint grammar) {
234    ESR_BOOL rtn = ESR_FALSE;
235    checkEsrError(env, SR_RecognizerCheckGrammarConsistency((SR_Recognizer*)recognizer, (SR_Grammar*)grammar, &rtn));
236    return rtn;
237}
238
239static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerPutAudio
240        (JNIEnv *env, jclass clazz, jint 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
261static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerAdvance
262        (JNIEnv *env, jclass clazz, jint 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
270static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalClipping
271        (JNIEnv *env, jclass clazz, jint recognizer) {
272    ESR_BOOL rtn = ESR_FALSE;
273    checkEsrError(env, SR_RecognizerIsSignalClipping((SR_Recognizer*)recognizer, &rtn));
274    return rtn;
275}
276
277static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalDCOffset
278        (JNIEnv *env, jclass clazz, jint recognizer) {
279    ESR_BOOL rtn = ESR_FALSE;
280    checkEsrError(env, SR_RecognizerIsSignalDCOffset((SR_Recognizer*)recognizer, &rtn));
281    return rtn;
282}
283
284static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalNoisy
285        (JNIEnv *env, jclass clazz, jint recognizer) {
286    ESR_BOOL rtn = ESR_FALSE;
287    checkEsrError(env, SR_RecognizerIsSignalNoisy((SR_Recognizer*)recognizer, &rtn));
288    return rtn;
289}
290
291static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooQuiet
292        (JNIEnv *env, jclass clazz, jint recognizer) {
293    ESR_BOOL rtn = ESR_FALSE;
294    checkEsrError(env, SR_RecognizerIsSignalTooQuiet((SR_Recognizer*)recognizer, &rtn));
295    return rtn;
296}
297
298static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooFewSamples
299        (JNIEnv *env, jclass clazz, jint recognizer) {
300    ESR_BOOL rtn = ESR_FALSE;
301    checkEsrError(env, SR_RecognizerIsSignalTooFewSamples((SR_Recognizer*)recognizer, &rtn));
302    return rtn;
303}
304
305static JNIEXPORT jboolean JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooManySamples
306        (JNIEnv *env, jclass clazz, jint 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
317static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1AcousticStateReset
318        (JNIEnv *env, jclass clazz, jint recognizer) {
319    checkEsrError(env, SR_AcousticStateReset((SR_Recognizer*)recognizer));
320}
321
322static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1AcousticStateSet
323        (JNIEnv *env, jclass clazz, jint 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
329static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1AcousticStateGet
330        (JNIEnv *env, jclass clazz, jint recognizer) {
331    const LCHAR* st = NULL;
332    ESR_ReturnCode esr_status = SR_AcousticStateGet((SR_Recognizer*)recognizer, &st);
333    if (esr_status || st == NULL) {
334        checkEsrError(env, esr_status);
335        return NULL;
336    }
337    return env->NewStringUTF(st);
338}
339
340
341//////////////////////////////////////////////////////////////////////////
342// SR_Grammar JNI implementations
343//////////////////////////////////////////////////////////////////////////
344
345static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarCompile
346        (JNIEnv *env, jclass clazz, jint grammar) {
347    checkEsrError(env, SR_GrammarCompile((SR_Grammar*)grammar));
348}
349
350static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAddWordToSlot
351        (JNIEnv *env, jclass clazz, jint grammar, jstring slot, jstring word, jstring pronunciation, jint weight, jstring tag) {
352    const char* sl = 0;
353    const char* wo = 0;
354    const char* pr = 0;
355    const char* ta = 0;
356    if ((sl = env->GetStringUTFChars(slot, 0)) &&
357            (wo = env->GetStringUTFChars(word, 0)) &&
358            (!pronunciation || (pr = env->GetStringUTFChars(pronunciation, 0))) &&
359            (ta = env->GetStringUTFChars(tag, 0))) {
360        checkEsrError(env, SR_GrammarAddWordToSlot((SR_Grammar*)grammar, sl, wo, pr, weight, ta));
361    }
362    if (ta) env->ReleaseStringUTFChars(tag, ta);
363    if (pr) env->ReleaseStringUTFChars(pronunciation, pr);
364    if (wo) env->ReleaseStringUTFChars(word, wo);
365    if (sl) env->ReleaseStringUTFChars(slot, sl);
366}
367
368static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarResetAllSlots
369        (JNIEnv *env, jclass clazz, jint grammar) {
370    checkEsrError(env, SR_GrammarResetAllSlots((SR_Grammar*)grammar));
371}
372
373static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSetupVocabulary
374        (JNIEnv *env, jclass clazz, jint grammar, jint vocabulary) {
375    checkEsrError(env, SR_GrammarSetupVocabulary((SR_Grammar*)grammar, (SR_Vocabulary*)vocabulary));
376}
377
378static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSetupRecognizer
379        (JNIEnv *env, jclass clazz, jint grammar, jint recognizer) {
380    checkEsrError(env, SR_GrammarSetupRecognizer((SR_Grammar*)grammar, (SR_Recognizer*)recognizer));
381}
382
383static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarUnsetupRecognizer
384        (JNIEnv *env, jclass clazz, jint grammar) {
385    checkEsrError(env, SR_GrammarUnsetupRecognizer((SR_Grammar*)grammar));
386}
387
388static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarCreate
389        (JNIEnv *env, jclass clazz) {
390    SR_Grammar* grammar = 0;
391    checkEsrError(env, SR_GrammarCreate(&grammar));
392    return (jint)grammar;
393}
394
395static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarDestroy
396        (JNIEnv *env, jclass clazz, jint grammar) {
397    checkEsrError(env, SR_GrammarDestroy((SR_Grammar*)grammar));
398}
399
400static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarLoad
401        (JNIEnv *env, jclass clazz, jstring fileName) {
402    // TODO: check for fileName NPE
403    SR_Grammar* grammar = 0;
404    const char* fn = env->GetStringUTFChars(fileName, 0);
405    checkEsrError(env, SR_GrammarLoad(fn, &grammar));
406    env->ReleaseStringUTFChars(fileName, fn);
407    return (jint)grammar;
408}
409
410static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSave
411        (JNIEnv *env, jclass clazz, jint grammar, jstring fileName) {
412    const char* fn = env->GetStringUTFChars(fileName, 0);
413    checkEsrError(env, SR_GrammarSave((SR_Grammar*)grammar, fn));
414    env->ReleaseStringUTFChars(fileName, fn);
415}
416
417static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAllowOnly
418        (JNIEnv *env, jclass clazz, jint grammar, jstring transcription) {
419    const char* tr = env->GetStringUTFChars(transcription, 0);
420    checkEsrError(env, SR_GrammarSave((SR_Grammar*)grammar, tr));
421    env->ReleaseStringUTFChars(transcription, tr);
422}
423
424static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAllowAll
425        (JNIEnv *env, jclass clazz, jint grammar) {
426    checkEsrError(env, SR_GrammarAllowAll((SR_Grammar*)grammar));
427}
428
429
430//////////////////////////////////////////////////////////////////////////
431// SR_Vocabulary JNI implementations
432//////////////////////////////////////////////////////////////////////////
433
434static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyLoad
435        (JNIEnv *env, jclass clazz) {
436    char filename[P_PATH_MAX];
437    size_t flen = sizeof(filename) - 1;
438    checkEsrError(env, ESR_SessionGetLCHAR ( L("cmdline.vocabulary"), filename, &flen ));
439    filename[sizeof(filename) - 1] = 0;
440    // TODO: do we need to clean up the recognizer if this fails?
441    SR_Vocabulary* vocabulary = NULL;
442    checkEsrError(env, SR_VocabularyLoad(filename, &vocabulary));
443    return (jint)vocabulary;
444}
445
446static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyDestroy
447        (JNIEnv *env, jclass clazz, jint vocabulary) {
448    // TODO: do we need to clean up the recognizer if this fails?
449    checkEsrError(env, SR_VocabularyDestroy((SR_Vocabulary*)vocabulary));
450}
451
452static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyGetPronunciation
453        (JNIEnv *env, jclass clazz, jint vocabulary, jstring word) {
454    char rtn[1000];
455    size_t rtnLength = sizeof(rtn) - 1;
456    const char* wo = env->GetStringUTFChars(word, 0);
457    ESR_ReturnCode esr_status = SR_VocabularyGetPronunciation((SR_Vocabulary*)vocabulary, wo, rtn, &rtnLength);
458    env->ReleaseStringUTFChars(word, wo);
459    if (esr_status) {
460        checkEsrError(env, esr_status);
461        return NULL;
462    }
463    rtn[rtnLength] = 0;
464    return env->NewStringUTF(rtn);
465}
466
467
468//////////////////////////////////////////////////////////////////////////
469// SR_RecognizerResult JNI implementations
470//////////////////////////////////////////////////////////////////////////
471
472static JNIEXPORT jbyteArray JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetWaveform
473        (JNIEnv *env, jclass clazz, jint recognizer) {
474    unimplemented(env);
475    return 0;
476}
477
478static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetSize
479        (JNIEnv *env, jclass clazz, jint recognizer) {
480    size_t size = 0;
481    checkEsrError(env, SR_RecognizerResultGetSize(((SR_RecognizerImpl*)recognizer)->result, &size));
482    return size;
483}
484
485static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyCount
486        (JNIEnv *env, jclass clazz, jint recognizer, jint nbest) {
487    size_t size = 0;
488    checkEsrError(env, SR_RecognizerResultGetKeyCount(((SR_RecognizerImpl*)recognizer)->result, nbest, &size));
489    return size;
490}
491
492static JNIEXPORT jobjectArray JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyList
493        (JNIEnv *env, jclass clazz, jint recognizer, jint nbest) {
494    unimplemented(env);
495    return NULL;
496}
497
498static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetValue
499        (JNIEnv *env, jclass clazz, jint recognizer, jint nbest, jstring key) {
500    char rtn[1000];
501    size_t rtnLength = sizeof(rtn) - 1;
502    const char* ke = env->GetStringUTFChars(key, 0);
503    ESR_ReturnCode esr_status = SR_RecognizerResultGetValue(((SR_RecognizerImpl*)recognizer)->result, nbest, ke, rtn, &rtnLength);
504    env->ReleaseStringUTFChars(key, ke);
505    if (esr_status) {
506        checkEsrError(env, esr_status);
507        return NULL;
508    }
509    rtn[rtnLength] = 0;
510    return env->NewStringUTF(rtn);
511}
512
513
514/*
515 * Table of methods associated with a single class.
516 */
517static JNINativeMethod gMethods[] = {
518    /* name, signature, funcPtr */
519    // PMem
520    {"PMemInit",                           "()V",                     (void*)Java_android_speech_srec_Recognizer_PMemInit},
521    {"PMemShutdown",                       "()V",                     (void*)Java_android_speech_srec_Recognizer_PMemShutdown},
522    // SR_Session
523    {"SR_SessionCreate",                   "(Ljava/lang/String;)V",   (void*)Java_android_speech_srec_Recognizer_SR_1SessionCreate},
524    {"SR_SessionDestroy",                  "()V",                     (void*)Java_android_speech_srec_Recognizer_SR_1SessionDestroy},
525    // SR_Recognizer
526    {"SR_RecognizerStart",                 "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerStart},
527    {"SR_RecognizerStop",                  "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerStop},
528    {"SR_RecognizerCreate",                "()I",                     (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerCreate},
529    {"SR_RecognizerDestroy",               "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDestroy},
530    {"SR_RecognizerSetup",                 "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetup},
531    {"SR_RecognizerUnsetup",               "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerUnsetup},
532    {"SR_RecognizerIsSetup",               "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSetup},
533    {"SR_RecognizerGetParameter",          "(ILjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetParameter},
534    {"SR_RecognizerGetSize_tParameter",    "(ILjava/lang/String;)I",  (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetSize_1tParameter},
535    {"SR_RecognizerGetBoolParameter",      "(ILjava/lang/String;)Z",  (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetBoolParameter},
536    {"SR_RecognizerSetParameter",          "(ILjava/lang/String;Ljava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetParameter},
537    {"SR_RecognizerSetSize_tParameter",    "(ILjava/lang/String;I)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetSize_1tParameter},
538    {"SR_RecognizerSetBoolParameter",      "(ILjava/lang/String;Z)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetBoolParameter},
539    {"SR_RecognizerSetupRule",             "(IILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetupRule},
540    {"SR_RecognizerHasSetupRules",         "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerHasSetupRules},
541    {"SR_RecognizerActivateRule",          "(IILjava/lang/String;I)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerActivateRule},
542    {"SR_RecognizerDeactivateRule",        "(IILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateRule},
543    {"SR_RecognizerDeactivateAllRules",    "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateAllRules},
544    {"SR_RecognizerIsActiveRule",          "(IILjava/lang/String;)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsActiveRule},
545    {"SR_RecognizerCheckGrammarConsistency", "(II)Z",                 (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerCheckGrammarConsistency},
546    {"SR_RecognizerPutAudio",              "(I[BIIZ)I",               (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerPutAudio},
547    {"SR_RecognizerAdvance",               "(I)I",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerAdvance},
548    {"SR_RecognizerIsSignalClipping",      "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalClipping},
549    {"SR_RecognizerIsSignalDCOffset",      "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalDCOffset},
550    {"SR_RecognizerIsSignalNoisy",         "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalNoisy},
551    {"SR_RecognizerIsSignalTooQuiet",      "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooQuiet},
552    {"SR_RecognizerIsSignalTooFewSamples", "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooFewSamples},
553    {"SR_RecognizerIsSignalTooManySamples", "(I)Z",                   (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooManySamples},
554    // SR_AcousticState
555    {"SR_AcousticStateReset",               "(I)V",                   (void*)Java_android_speech_srec_Recognizer_SR_1AcousticStateReset},
556    {"SR_AcousticStateSet",                 "(ILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1AcousticStateSet},
557    {"SR_AcousticStateGet",                 "(I)Ljava/lang/String;",  (void*)Java_android_speech_srec_Recognizer_SR_1AcousticStateGet},
558    // SR_Grammar
559    {"SR_GrammarCompile",                  "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarCompile},
560    {"SR_GrammarAddWordToSlot",            "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAddWordToSlot},
561    {"SR_GrammarResetAllSlots",            "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarResetAllSlots},
562    {"SR_GrammarSetupVocabulary",          "(II)V",                   (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSetupVocabulary},
563    {"SR_GrammarSetupRecognizer",          "(II)V",                   (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSetupRecognizer},
564    {"SR_GrammarUnsetupRecognizer",        "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarUnsetupRecognizer},
565    {"SR_GrammarCreate",                   "()I",                     (void*)Java_android_speech_srec_Recognizer_SR_1GrammarCreate},
566    {"SR_GrammarDestroy",                  "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarDestroy},
567    {"SR_GrammarLoad",                     "(Ljava/lang/String;)I",   (void*)Java_android_speech_srec_Recognizer_SR_1GrammarLoad},
568    {"SR_GrammarSave",                     "(ILjava/lang/String;)V",  (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSave},
569    {"SR_GrammarAllowOnly",                "(ILjava/lang/String;)V",  (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAllowOnly},
570    {"SR_GrammarAllowAll",                 "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAllowAll},
571    // SR_Vocabulary
572    {"SR_VocabularyLoad",                  "()I",                     (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyLoad},
573    {"SR_VocabularyDestroy",               "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyDestroy},
574    {"SR_VocabularyGetPronunciation",      "(ILjava/lang/String;)Ljava/lang/String;",  (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyGetPronunciation},
575    // SR_RecognizerResult
576    {"SR_RecognizerResultGetWaveform",     "(I)[B",                   (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetWaveform},
577    {"SR_RecognizerResultGetSize",         "(I)I",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetSize},
578    {"SR_RecognizerResultGetKeyCount",     "(II)I",                   (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyCount},
579    {"SR_RecognizerResultGetKeyList",      "(II)[Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyList},
580    {"SR_RecognizerResultGetValue",        "(IILjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetValue},
581};
582
583/*
584 * Returns the JNI version on success, -1 on failure.
585 */
586jint register_android_speech_srec_Recognizer(JavaVM* vm, void* reserved)
587{
588    JNIEnv* env = NULL;
589    jclass clazz = NULL;
590    const char* className = "android/speech/srec/Recognizer";
591
592    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
593        LOGE("ERROR: GetEnv failed\n");
594        return -1;
595    }
596    assert(env != NULL);
597
598    clazz = env->FindClass(className);
599    if (clazz == NULL) {
600        LOGE("Native registration unable to find class '%s'\n", className);
601        return -1;
602    }
603    if (env->RegisterNatives(clazz, gMethods,
604            sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
605        LOGE("RegisterNatives failed for '%s'\n", className);
606        return -1;
607    }
608
609    /* success -- return valid version number */
610    return JNI_VERSION_1_4;
611}
612
613
614extern jint register_android_speech_srec_MicrophoneInputStream(JavaVM* vm, void* reserved);
615
616jint JNI_OnLoad(JavaVM* vm, void* reserved)
617{
618    if (register_android_speech_srec_MicrophoneInputStream(vm, reserved) != JNI_VERSION_1_4 ||
619        register_android_speech_srec_Recognizer(vm, reserved) != JNI_VERSION_1_4) return -1;
620    return JNI_VERSION_1_4;
621}
622