android_speech_srec_Recognizer.cpp revision 2ebd1d2ce82c4f10284c70a28ea62535349a7334
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_Grammar JNI implementations
315//////////////////////////////////////////////////////////////////////////
316
317static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarCompile
318        (JNIEnv *env, jclass clazz, jint grammar) {
319    checkEsrError(env, SR_GrammarCompile((SR_Grammar*)grammar));
320}
321
322static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAddWordToSlot
323        (JNIEnv *env, jclass clazz, jint grammar, jstring slot, jstring word, jstring pronunciation, jint weight, jstring tag) {
324    const char* sl = 0;
325    const char* wo = 0;
326    const char* pr = 0;
327    const char* ta = 0;
328    if ((sl = env->GetStringUTFChars(slot, 0)) &&
329            (wo = env->GetStringUTFChars(word, 0)) &&
330            (!pronunciation || (pr = env->GetStringUTFChars(pronunciation, 0))) &&
331            (ta = env->GetStringUTFChars(tag, 0))) {
332        checkEsrError(env, SR_GrammarAddWordToSlot((SR_Grammar*)grammar, sl, wo, pr, weight, ta));
333    }
334    if (ta) env->ReleaseStringUTFChars(tag, ta);
335    if (pr) env->ReleaseStringUTFChars(pronunciation, pr);
336    if (wo) env->ReleaseStringUTFChars(word, wo);
337    if (sl) env->ReleaseStringUTFChars(slot, sl);
338}
339
340static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarResetAllSlots
341        (JNIEnv *env, jclass clazz, jint grammar) {
342    checkEsrError(env, SR_GrammarResetAllSlots((SR_Grammar*)grammar));
343}
344
345static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSetupVocabulary
346        (JNIEnv *env, jclass clazz, jint grammar, jint vocabulary) {
347    checkEsrError(env, SR_GrammarSetupVocabulary((SR_Grammar*)grammar, (SR_Vocabulary*)vocabulary));
348}
349
350static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSetupRecognizer
351        (JNIEnv *env, jclass clazz, jint grammar, jint recognizer) {
352    checkEsrError(env, SR_GrammarSetupRecognizer((SR_Grammar*)grammar, (SR_Recognizer*)recognizer));
353}
354
355static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarUnsetupRecognizer
356        (JNIEnv *env, jclass clazz, jint grammar) {
357    checkEsrError(env, SR_GrammarUnsetupRecognizer((SR_Grammar*)grammar));
358}
359
360static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarCreate
361        (JNIEnv *env, jclass clazz) {
362    SR_Grammar* grammar = 0;
363    checkEsrError(env, SR_GrammarCreate(&grammar));
364    return (jint)grammar;
365}
366
367static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarDestroy
368        (JNIEnv *env, jclass clazz, jint grammar) {
369    checkEsrError(env, SR_GrammarDestroy((SR_Grammar*)grammar));
370}
371
372static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarLoad
373        (JNIEnv *env, jclass clazz, jstring fileName) {
374    // TODO: check for fileName NPE
375    SR_Grammar* grammar = 0;
376    const char* fn = env->GetStringUTFChars(fileName, 0);
377    checkEsrError(env, SR_GrammarLoad(fn, &grammar));
378    env->ReleaseStringUTFChars(fileName, fn);
379    return (jint)grammar;
380}
381
382static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarSave
383        (JNIEnv *env, jclass clazz, jint grammar, jstring fileName) {
384    const char* fn = env->GetStringUTFChars(fileName, 0);
385    checkEsrError(env, SR_GrammarSave((SR_Grammar*)grammar, fn));
386    env->ReleaseStringUTFChars(fileName, fn);
387}
388
389static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAllowOnly
390        (JNIEnv *env, jclass clazz, jint grammar, jstring transcription) {
391    const char* tr = env->GetStringUTFChars(transcription, 0);
392    checkEsrError(env, SR_GrammarSave((SR_Grammar*)grammar, tr));
393    env->ReleaseStringUTFChars(transcription, tr);
394}
395
396static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1GrammarAllowAll
397        (JNIEnv *env, jclass clazz, jint grammar) {
398    checkEsrError(env, SR_GrammarAllowAll((SR_Grammar*)grammar));
399}
400
401
402//////////////////////////////////////////////////////////////////////////
403// SR_Vocabulary JNI implementations
404//////////////////////////////////////////////////////////////////////////
405
406static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyLoad
407        (JNIEnv *env, jclass clazz) {
408    char filename[P_PATH_MAX];
409    size_t flen = sizeof(filename) - 1;
410    checkEsrError(env, ESR_SessionGetLCHAR ( L("cmdline.vocabulary"), filename, &flen ));
411    filename[sizeof(filename) - 1] = 0;
412    // TODO: do we need to clean up the recognizer if this fails?
413    SR_Vocabulary* vocabulary = NULL;
414    checkEsrError(env, SR_VocabularyLoad(filename, &vocabulary));
415    return (jint)vocabulary;
416}
417
418static JNIEXPORT void JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyDestroy
419        (JNIEnv *env, jclass clazz, jint vocabulary) {
420    // TODO: do we need to clean up the recognizer if this fails?
421    checkEsrError(env, SR_VocabularyDestroy((SR_Vocabulary*)vocabulary));
422}
423
424static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1VocabularyGetPronunciation
425        (JNIEnv *env, jclass clazz, jint vocabulary, jstring word) {
426    char rtn[1000];
427    size_t rtnLength = sizeof(rtn) - 1;
428    const char* wo = env->GetStringUTFChars(word, 0);
429    ESR_ReturnCode esr_status = SR_VocabularyGetPronunciation((SR_Vocabulary*)vocabulary, wo, rtn, &rtnLength);
430    env->ReleaseStringUTFChars(word, wo);
431    if (esr_status) {
432        checkEsrError(env, esr_status);
433        return NULL;
434    }
435    rtn[rtnLength] = 0;
436    return env->NewStringUTF(rtn);
437}
438
439
440//////////////////////////////////////////////////////////////////////////
441// SR_RecognizerResult JNI implementations
442//////////////////////////////////////////////////////////////////////////
443
444static JNIEXPORT jbyteArray JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetWaveform
445        (JNIEnv *env, jclass clazz, jint recognizer) {
446    unimplemented(env);
447    return 0;
448}
449
450static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetSize
451        (JNIEnv *env, jclass clazz, jint recognizer) {
452    size_t size = 0;
453    checkEsrError(env, SR_RecognizerResultGetSize(((SR_RecognizerImpl*)recognizer)->result, &size));
454    return size;
455}
456
457static JNIEXPORT jint JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyCount
458        (JNIEnv *env, jclass clazz, jint recognizer, jint nbest) {
459    size_t size = 0;
460    checkEsrError(env, SR_RecognizerResultGetKeyCount(((SR_RecognizerImpl*)recognizer)->result, nbest, &size));
461    return size;
462}
463
464static JNIEXPORT jobjectArray JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyList
465        (JNIEnv *env, jclass clazz, jint recognizer, jint nbest) {
466    unimplemented(env);
467    return NULL;
468}
469
470static JNIEXPORT jstring JNICALL Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetValue
471        (JNIEnv *env, jclass clazz, jint recognizer, jint nbest, jstring key) {
472    char rtn[1000];
473    size_t rtnLength = sizeof(rtn) - 1;
474    const char* ke = env->GetStringUTFChars(key, 0);
475    ESR_ReturnCode esr_status = SR_RecognizerResultGetValue(((SR_RecognizerImpl*)recognizer)->result, nbest, ke, rtn, &rtnLength);
476    env->ReleaseStringUTFChars(key, ke);
477    if (esr_status) {
478        checkEsrError(env, esr_status);
479        return NULL;
480    }
481    rtn[rtnLength] = 0;
482    return env->NewStringUTF(rtn);
483}
484
485
486/*
487 * Table of methods associated with a single class.
488 */
489static JNINativeMethod gMethods[] = {
490    /* name, signature, funcPtr */
491    // PMem
492    {"PMemInit",                           "()V",                     (void*)Java_android_speech_srec_Recognizer_PMemInit},
493    {"PMemShutdown",                       "()V",                     (void*)Java_android_speech_srec_Recognizer_PMemShutdown},
494    // SR_Session
495    {"SR_SessionCreate",                   "(Ljava/lang/String;)V",   (void*)Java_android_speech_srec_Recognizer_SR_1SessionCreate},
496    {"SR_SessionDestroy",                  "()V",                     (void*)Java_android_speech_srec_Recognizer_SR_1SessionDestroy},
497    // SR_Recognizer
498    {"SR_RecognizerStart",                 "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerStart},
499    {"SR_RecognizerStop",                  "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerStop},
500    {"SR_RecognizerCreate",                "()I",                     (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerCreate},
501    {"SR_RecognizerDestroy",               "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDestroy},
502    {"SR_RecognizerSetup",                 "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetup},
503    {"SR_RecognizerUnsetup",               "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerUnsetup},
504    {"SR_RecognizerIsSetup",               "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSetup},
505    {"SR_RecognizerGetParameter",          "(ILjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetParameter},
506    {"SR_RecognizerGetSize_tParameter",    "(ILjava/lang/String;)I",  (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetSize_1tParameter},
507    {"SR_RecognizerGetBoolParameter",      "(ILjava/lang/String;)Z",  (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerGetBoolParameter},
508    {"SR_RecognizerSetParameter",          "(ILjava/lang/String;Ljava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetParameter},
509    {"SR_RecognizerSetSize_tParameter",    "(ILjava/lang/String;I)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetSize_1tParameter},
510    {"SR_RecognizerSetBoolParameter",      "(ILjava/lang/String;Z)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetBoolParameter},
511    {"SR_RecognizerSetupRule",             "(IILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerSetupRule},
512    {"SR_RecognizerHasSetupRules",         "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerHasSetupRules},
513    {"SR_RecognizerActivateRule",          "(IILjava/lang/String;I)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerActivateRule},
514    {"SR_RecognizerDeactivateRule",        "(IILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateRule},
515    {"SR_RecognizerDeactivateAllRules",    "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerDeactivateAllRules},
516    {"SR_RecognizerIsActiveRule",          "(IILjava/lang/String;)Z", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsActiveRule},
517    {"SR_RecognizerCheckGrammarConsistency", "(II)Z",                 (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerCheckGrammarConsistency},
518    {"SR_RecognizerPutAudio",              "(I[BIIZ)I",               (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerPutAudio},
519    {"SR_RecognizerAdvance",               "(I)I",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerAdvance},
520    {"SR_RecognizerIsSignalClipping",      "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalClipping},
521    {"SR_RecognizerIsSignalDCOffset",      "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalDCOffset},
522    {"SR_RecognizerIsSignalNoisy",         "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalNoisy},
523    {"SR_RecognizerIsSignalTooQuiet",      "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooQuiet},
524    {"SR_RecognizerIsSignalTooFewSamples", "(I)Z",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooFewSamples},
525    {"SR_RecognizerIsSignalTooManySamples", "(I)Z",                   (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerIsSignalTooManySamples},
526    // SR_Grammar
527    {"SR_GrammarCompile",                  "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarCompile},
528    {"SR_GrammarAddWordToSlot",            "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V", (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAddWordToSlot},
529    {"SR_GrammarResetAllSlots",            "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarResetAllSlots},
530    {"SR_GrammarSetupVocabulary",          "(II)V",                   (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSetupVocabulary},
531    {"SR_GrammarSetupRecognizer",          "(II)V",                   (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSetupRecognizer},
532    {"SR_GrammarUnsetupRecognizer",        "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarUnsetupRecognizer},
533    {"SR_GrammarCreate",                   "()I",                     (void*)Java_android_speech_srec_Recognizer_SR_1GrammarCreate},
534    {"SR_GrammarDestroy",                  "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarDestroy},
535    {"SR_GrammarLoad",                     "(Ljava/lang/String;)I",   (void*)Java_android_speech_srec_Recognizer_SR_1GrammarLoad},
536    {"SR_GrammarSave",                     "(ILjava/lang/String;)V",  (void*)Java_android_speech_srec_Recognizer_SR_1GrammarSave},
537    {"SR_GrammarAllowOnly",                "(ILjava/lang/String;)V",  (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAllowOnly},
538    {"SR_GrammarAllowAll",                 "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1GrammarAllowAll},
539    // SR_Vocabulary
540    {"SR_VocabularyLoad",                  "()I",                     (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyLoad},
541    {"SR_VocabularyDestroy",               "(I)V",                    (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyDestroy},
542    {"SR_VocabularyGetPronunciation",      "(ILjava/lang/String;)Ljava/lang/String;",  (void*)Java_android_speech_srec_Recognizer_SR_1VocabularyGetPronunciation},
543    // SR_RecognizerResult
544    {"SR_RecognizerResultGetWaveform",     "(I)[B",                   (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetWaveform},
545    {"SR_RecognizerResultGetSize",         "(I)I",                    (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetSize},
546    {"SR_RecognizerResultGetKeyCount",     "(II)I",                   (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyCount},
547    {"SR_RecognizerResultGetKeyList",      "(II)[Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetKeyList},
548    {"SR_RecognizerResultGetValue",        "(IILjava/lang/String;)Ljava/lang/String;", (void*)Java_android_speech_srec_Recognizer_SR_1RecognizerResultGetValue},
549};
550
551/*
552 * Returns the JNI version on success, -1 on failure.
553 */
554jint register_android_speech_srec_Recognizer(JavaVM* vm, void* reserved)
555{
556    JNIEnv* env = NULL;
557    jclass clazz = NULL;
558    const char* className = "android/speech/srec/Recognizer";
559
560    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
561        LOGE("ERROR: GetEnv failed\n");
562        return -1;
563    }
564    assert(env != NULL);
565
566    clazz = env->FindClass(className);
567    if (clazz == NULL) {
568        LOGE("Native registration unable to find class '%s'\n", className);
569        return -1;
570    }
571    if (env->RegisterNatives(clazz, gMethods,
572            sizeof(gMethods) / sizeof(gMethods[0])) < 0) {
573        LOGE("RegisterNatives failed for '%s'\n", className);
574        return -1;
575    }
576
577    /* success -- return valid version number */
578    return JNI_VERSION_1_4;
579}
580
581
582extern jint register_android_speech_srec_MicrophoneInputStream(JavaVM* vm, void* reserved);
583
584jint JNI_OnLoad(JavaVM* vm, void* reserved)
585{
586    if (register_android_speech_srec_MicrophoneInputStream(vm, reserved) != JNI_VERSION_1_4 ||
587        register_android_speech_srec_Recognizer(vm, reserved) != JNI_VERSION_1_4) return -1;
588    return JNI_VERSION_1_4;
589}
590