1/*
2 * ---------------------------------------------------------------------------
3 * Recognizer.java
4 *
5 * Copyright 2007 Nuance Communciations, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the 'License'); you may not
8 * use this file except in compliance with the License.
9 *
10 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 * License for the specific language governing permissions and limitations under
17 * the License.
18 *
19 * ---------------------------------------------------------------------------
20 */
21
22
23package android.speech.srec;
24
25import android.util.Log;
26
27import java.io.File;
28import java.io.InputStream;
29import java.io.IOException;
30import java.util.Locale;
31
32/**
33 * Simple, synchronous speech recognizer, using the Nuance SREC package.
34 * Usages proceeds as follows:
35 *
36 * <ul>
37 * <li>Create a <code>Recognizer</code>.
38 * <li>Create a <code>Recognizer.Grammar</code>.
39 * <li>Setup the <code>Recognizer.Grammar</code>.
40 * <li>Reset the <code>Recognizer.Grammar</code> slots, if needed.
41 * <li>Fill the <code>Recognizer.Grammar</code> slots, if needed.
42 * <li>Compile the <code>Recognizer.Grammar</code>, if needed.
43 * <li>Save the filled <code>Recognizer.Grammar</code>, if needed.
44 * <li>Start the <code>Recognizer</code>.
45 * <li>Loop over <code>advance</code> and <code>putAudio</code> until recognition complete.
46 * <li>Fetch and process results, or notify of failure.
47 * <li>Stop the <code>Recognizer</code>.
48 * <li>Destroy the <code>Recognizer</code>.
49 * </ul>
50 *
51 * <p>Below is example code</p>
52 *
53 * <pre class="prettyprint">
54 *
55 * // create and start audio input
56 * InputStream audio = new MicrophoneInputStream(11025, 11025*5);
57 * // create a Recognizer
58 * String cdir = Recognizer.getConfigDir(null);
59 * Recognizer recognizer = new Recognizer(cdir + "/baseline11k.par");
60 * // create and load a Grammar
61 * Recognizer.Grammar grammar = recognizer.new Grammar(cdir + "/grammars/VoiceDialer.g2g");
62 * // setup the Grammar to work with the Recognizer
63 * grammar.setupRecognizer();
64 * // fill the Grammar slots with names and save, if required
65 * grammar.resetAllSlots();
66 * for (String name : names) grammar.addWordToSlot("@Names", name, null, 1, "V=1");
67 * grammar.compile();
68 * grammar.save(".../foo.g2g");
69 * // start the Recognizer
70 * recognizer.start();
71 * // loop over Recognizer events
72 * while (true) {
73 *     switch (recognizer.advance()) {
74 *     case Recognizer.EVENT_INCOMPLETE:
75 *     case Recognizer.EVENT_STARTED:
76 *     case Recognizer.EVENT_START_OF_VOICING:
77 *     case Recognizer.EVENT_END_OF_VOICING:
78 *         // let the Recognizer continue to run
79 *         continue;
80 *     case Recognizer.EVENT_RECOGNITION_RESULT:
81 *         // success, so fetch results here!
82 *         for (int i = 0; i < recognizer.getResultCount(); i++) {
83 *             String result = recognizer.getResult(i, Recognizer.KEY_LITERAL);
84 *         }
85 *         break;
86 *     case Recognizer.EVENT_NEED_MORE_AUDIO:
87 *         // put more audio in the Recognizer
88 *         recognizer.putAudio(audio);
89 *         continue;
90 *     default:
91 *         notifyFailure();
92 *         break;
93 *     }
94 *     break;
95 * }
96 * // stop the Recognizer
97 * recognizer.stop();
98 * // destroy the Recognizer
99 * recognizer.destroy();
100 * // stop the audio device
101 * audio.close();
102 *
103 * </pre>
104 */
105public final class Recognizer {
106    static {
107        System.loadLibrary("srec_jni");
108    }
109
110    private static String TAG = "Recognizer";
111
112    /**
113     * Result key corresponding to confidence score.
114     */
115    public static final String KEY_CONFIDENCE = "conf";
116
117    /**
118     * Result key corresponding to literal text.
119     */
120    public static final String KEY_LITERAL = "literal";
121
122    /**
123     * Result key corresponding to semantic meaning text.
124     */
125    public static final String KEY_MEANING = "meaning";
126
127    // handle to SR_Vocabulary object
128    private int mVocabulary = 0;
129
130    // handle to SR_Recognizer object
131    private int mRecognizer = 0;
132
133    // Grammar currently associated with Recognizer via SR_GrammarSetupRecognizer
134    private Grammar mActiveGrammar = null;
135
136    /**
137     * Get the pathname of the SREC configuration directory corresponding to the
138     * language indicated by the Locale.
139     * This directory contains dictionaries, speech models,
140     * configuration files, and other data needed by the Recognizer.
141     * @param locale <code>Locale</code> corresponding to the desired language,
142     * or null for default, currently <code>Locale.US</code>.
143     * @return Pathname of the configuration directory.
144     */
145    public static String getConfigDir(Locale locale) {
146        if (locale == null) locale = Locale.US;
147        String dir = "/system/usr/srec/config/" +
148                locale.toString().replace('_', '.').toLowerCase();
149        if ((new File(dir)).isDirectory()) return dir;
150        return null;
151    }
152
153    /**
154     * Create an instance of a SREC speech recognizer.
155     *
156     * @param configFile pathname of the baseline*.par configuration file,
157     * which in turn contains references to dictionaries, speech models,
158     * and other data needed to configure and operate the recognizer.
159     * A separate config file is needed for each audio sample rate.
160     * Two files, baseline11k.par and baseline8k.par, which correspond to
161     * 11025 and 8000 hz, are present in the directory indicated by
162     * {@link #getConfigDir}.
163     * @throws IOException
164     */
165    public Recognizer(String configFile) throws IOException {
166        PMemInit();
167        SR_SessionCreate(configFile);
168        mRecognizer = SR_RecognizerCreate();
169        SR_RecognizerSetup(mRecognizer);
170        mVocabulary = SR_VocabularyLoad();
171    }
172
173    /**
174     * Represents a grammar loaded into the Recognizer.
175     */
176    public class Grammar {
177        private int mGrammar = 0;
178
179        /**
180         * Create a <code>Grammar</code> instance.
181         * @param g2gFileName pathname of g2g file.
182         */
183        public Grammar(String g2gFileName) throws IOException {
184            mGrammar = SR_GrammarLoad(g2gFileName);
185            SR_GrammarSetupVocabulary(mGrammar, mVocabulary);
186        }
187
188        /**
189         * Reset all slots.
190         */
191        public void resetAllSlots() {
192            SR_GrammarResetAllSlots(mGrammar);
193        }
194
195        /**
196         * Add a word to a slot.
197         *
198         * @param slot slot name.
199         * @param word word to insert.
200         * @param pron pronunciation, or null to derive from word.
201         * @param weight weight to give the word.  One is normal, 50 is low.
202         * @param tag semantic meaning tag string.
203         */
204        public void addWordToSlot(String slot, String word, String pron, int weight, String tag) {
205            SR_GrammarAddWordToSlot(mGrammar, slot, word, pron, weight, tag);
206        }
207
208        /**
209         * Compile all slots.
210         */
211        public void compile() {
212            SR_GrammarCompile(mGrammar);
213        }
214
215        /**
216         * Setup <code>Grammar</code> with <code>Recognizer</code>.
217         */
218        public void setupRecognizer() {
219            SR_GrammarSetupRecognizer(mGrammar, mRecognizer);
220            mActiveGrammar = this;
221        }
222
223        /**
224         * Save <code>Grammar</code> to g2g file.
225         *
226         * @param g2gFileName
227         * @throws IOException
228         */
229        public void save(String g2gFileName) throws IOException {
230            SR_GrammarSave(mGrammar, g2gFileName);
231        }
232
233        /**
234         * Release resources associated with this <code>Grammar</code>.
235         */
236        public void destroy() {
237            // TODO: need to do cleanup and disassociation with Recognizer
238            if (mGrammar != 0) {
239                SR_GrammarDestroy(mGrammar);
240                mGrammar = 0;
241            }
242        }
243
244        /**
245         * Clean up resources.
246         */
247        protected void finalize() {
248            if (mGrammar != 0) {
249                destroy();
250                throw new IllegalStateException("someone forgot to destroy Grammar");
251            }
252        }
253    }
254
255    /**
256     * Start recognition
257     */
258    public void start() {
259        // TODO: shouldn't be here?
260        SR_RecognizerActivateRule(mRecognizer, mActiveGrammar.mGrammar, "trash", 1);
261        SR_RecognizerStart(mRecognizer);
262    }
263
264    /**
265     * Process some audio and return the current status.
266     * @return recognition event, one of:
267     * <ul>
268     * <li><code>EVENT_INVALID</code>
269     * <li><code>EVENT_NO_MATCH</code>
270     * <li><code>EVENT_INCOMPLETE</code>
271     * <li><code>EVENT_STARTED</code>
272     * <li><code>EVENT_STOPPED</code>
273     * <li><code>EVENT_START_OF_VOICING</code>
274     * <li><code>EVENT_END_OF_VOICING</code>
275     * <li><code>EVENT_SPOKE_TOO_SOON</code>
276     * <li><code>EVENT_RECOGNITION_RESULT</code>
277     * <li><code>EVENT_START_OF_UTTERANCE_TIMEOUT</code>
278     * <li><code>EVENT_RECOGNITION_TIMEOUT</code>
279     * <li><code>EVENT_NEED_MORE_AUDIO</code>
280     * <li><code>EVENT_MAX_SPEECH</code>
281     * </ul>
282     */
283    public int advance() {
284        return SR_RecognizerAdvance(mRecognizer);
285    }
286
287    /**
288     * Put audio samples into the <code>Recognizer</code>.
289     * @param buf holds the audio samples.
290     * @param offset offset of the first sample.
291     * @param length number of bytes containing samples.
292     * @param isLast indicates no more audio data, normally false.
293     * @return number of bytes accepted.
294     */
295    public int putAudio(byte[] buf, int offset, int length, boolean isLast) {
296        return SR_RecognizerPutAudio(mRecognizer, buf, offset, length, isLast);
297    }
298
299    /**
300     * Read audio samples from an <code>InputStream</code> and put them in the
301     * <code>Recognizer</code>.
302     * @param audio <code>InputStream</code> containing PCM audio samples.
303     */
304    public void putAudio(InputStream audio) throws IOException {
305        // make sure the audio buffer is allocated
306        if (mPutAudioBuffer == null) mPutAudioBuffer = new byte[512];
307        // read some data
308        int nbytes = audio.read(mPutAudioBuffer);
309        // eof, so signal Recognizer
310        if (nbytes == -1) {
311            SR_RecognizerPutAudio(mRecognizer, mPutAudioBuffer, 0, 0, true);
312        }
313        // put it into the Recognizer
314        else if (nbytes != SR_RecognizerPutAudio(mRecognizer, mPutAudioBuffer, 0, nbytes, false)) {
315            throw new IOException("SR_RecognizerPutAudio failed nbytes=" + nbytes);
316        }
317    }
318
319    // audio buffer for putAudio(InputStream)
320    private byte[] mPutAudioBuffer = null;
321
322    /**
323     * Get the number of recognition results.  Must be called after
324     * <code>EVENT_RECOGNITION_RESULT</code> is returned by
325     * <code>advance</code>, but before <code>stop</code>.
326     *
327     * @return number of results in nbest list.
328     */
329    public int getResultCount() {
330        return SR_RecognizerResultGetSize(mRecognizer);
331    }
332
333    /**
334     * Get a set of keys for the result.  Must be called after
335     * <code>EVENT_RECOGNITION_RESULT</code> is returned by
336     * <code>advance</code>, but before <code>stop</code>.
337     *
338     * @param index index of result.
339     * @return array of keys.
340     */
341    public String[] getResultKeys(int index) {
342        return SR_RecognizerResultGetKeyList(mRecognizer, index);
343    }
344
345    /**
346     * Get a result value.  Must be called after
347     * <code>EVENT_RECOGNITION_RESULT</code> is returned by
348     * <code>advance</code>, but before <code>stop</code>.
349     *
350     * @param index index of the result.
351     * @param key key of the result.  This is typically one of
352     * <code>KEY_CONFIDENCE</code>, <code>KEY_LITERAL</code>, or
353     * <code>KEY_MEANING</code>, but the user can also define their own keys
354     * in a grxml file, or in the <code>tag</code> slot of
355     * <code>Grammar.addWordToSlot</code>.
356     * @return the result.
357     */
358    public String getResult(int index, String key) {
359        return SR_RecognizerResultGetValue(mRecognizer, index, key);
360    }
361
362    /**
363     * Stop the <code>Recognizer</code>.
364     */
365    public void stop() {
366        SR_RecognizerStop(mRecognizer);
367        SR_RecognizerDeactivateRule(mRecognizer, mActiveGrammar.mGrammar, "trash");
368    }
369
370    /**
371     * Reset the acoustic state vectorto it's default value.
372     *
373     * @hide
374     */
375    public void resetAcousticState() {
376        SR_AcousticStateReset(mRecognizer);
377    }
378
379    /**
380     * Set the acoustic state vector.
381     * @param state String containing the acoustic state vector.
382     *
383     * @hide
384     */
385    public void setAcousticState(String state) {
386        SR_AcousticStateSet(mRecognizer, state);
387    }
388
389    /**
390     * Get the acoustic state vector.
391     * @return String containing the acoustic state vector.
392     *
393     * @hide
394     */
395    public String getAcousticState() {
396        return SR_AcousticStateGet(mRecognizer);
397    }
398
399    /**
400     * Clean up resources.
401     */
402    public void destroy() {
403        try {
404            if (mVocabulary != 0) SR_VocabularyDestroy(mVocabulary);
405        } finally {
406            mVocabulary = 0;
407            try {
408                if (mRecognizer != 0) SR_RecognizerUnsetup(mRecognizer);
409            } finally {
410                try {
411                    if (mRecognizer != 0) SR_RecognizerDestroy(mRecognizer);
412                } finally {
413                    mRecognizer = 0;
414                    try {
415                        SR_SessionDestroy();
416                    } finally {
417                        PMemShutdown();
418                    }
419                }
420            }
421        }
422    }
423
424    /**
425     * Clean up resources.
426     */
427    protected void finalize() throws Throwable {
428        if (mVocabulary != 0 || mRecognizer != 0) {
429            destroy();
430            throw new IllegalStateException("someone forgot to destroy Recognizer");
431        }
432    }
433
434    /* an example session captured, for reference
435    void doall() {
436        if (PMemInit ( )
437           || lhs_audioinOpen ( WAVE_MAPPER, SREC_TEST_DEFAULT_AUDIO_FREQUENCY, &audio_in_handle )
438           || srec_test_init_application_data ( &applicationData, argc, argv )
439           || SR_SessionCreate ( "/system/usr/srec/config/en.us/baseline11k.par" )
440           || SR_RecognizerCreate ( &applicationData.recognizer )
441           || SR_RecognizerSetup ( applicationData.recognizer)
442           || ESR_SessionGetLCHAR ( L("cmdline.vocabulary"), filename, &flen )
443           || SR_VocabularyLoad ( filename, &applicationData.vocabulary )
444           || SR_VocabularyGetLanguage ( applicationData.vocabulary, &applicationData.locale )
445           || (applicationData.nametag = NULL)
446           || SR_NametagsCreate ( &applicationData.nametags )
447           || (LSTRCPY ( applicationData.grammars [0].grammar_path, "/system/usr/srec/config/en.us/grammars/VoiceDialer.g2g" ), 0)
448           || (LSTRCPY ( applicationData.grammars [0].grammarID, "BothTags" ), 0)
449           || (LSTRCPY ( applicationData.grammars [0].ruleName, "trash" ), 0)
450           || (applicationData.grammars [0].is_ve_grammar = ESR_FALSE, 0)
451           || SR_GrammarLoad (applicationData.grammars [0].grammar_path, &applicationData.grammars [applicationData.grammarCount].grammar )
452           || SR_GrammarSetupVocabulary ( applicationData.grammars [0].grammar, applicationData.vocabulary )
453           || SR_GrammarSetupRecognizer( applicationData.grammars [0].grammar, applicationData.recognizer )
454           || SR_GrammarSetDispatchFunction ( applicationData.grammars [0].grammar, L("myDSMCallback"), NULL, myDSMCallback )
455           || (applicationData.grammarCount++, 0)
456           || SR_RecognizerActivateRule ( applicationData.recognizer, applicationData.grammars [0].grammar,
457                           applicationData.grammars [0].ruleName, 1 )
458           || (applicationData.active_grammar_num = 0, 0)
459           || lhs_audioinStart ( audio_in_handle )
460           || SR_RecognizerStart ( applicationData.recognizer )
461           || strl ( applicationData.grammars [0].grammar, &applicationData, audio_in_handle, &recognition_count )
462           || SR_RecognizerStop ( applicationData.recognizer )
463           || lhs_audioinStop ( audio_in_handle )
464           || SR_RecognizerDeactivateRule ( applicationData.recognizer, applicationData.grammars [0].grammar, applicationData.grammars [0].ruleName )
465           || (applicationData.active_grammar_num = -1, 0)
466           || SR_GrammarDestroy ( applicationData.grammars [0].grammar )
467           || (applicationData.grammarCount--, 0)
468           || SR_NametagsDestroy ( applicationData.nametags )
469           || (applicationData.nametags = NULL, 0)
470           || SR_VocabularyDestroy ( applicationData.vocabulary )
471           || (applicationData.vocabulary = NULL)
472           || SR_RecognizerUnsetup ( applicationData.recognizer) // releases acoustic models
473           || SR_RecognizerDestroy ( applicationData.recognizer )
474           || (applicationData.recognizer = NULL)
475           || SR_SessionDestroy ( )
476           || srec_test_shutdown_application_data ( &applicationData )
477           || lhs_audioinClose ( &audio_in_handle )
478           || PMemShutdown ( )
479    }
480    */
481
482
483    //
484    // PMem native methods
485    //
486    private static native void PMemInit();
487    private static native void PMemShutdown();
488
489
490    //
491    // SR_Session native methods
492    //
493    private static native void SR_SessionCreate(String filename);
494    private static native void SR_SessionDestroy();
495
496
497    //
498    // SR_Recognizer native methods
499    //
500
501    /**
502     * Reserved value.
503     */
504    public final static int EVENT_INVALID = 0;
505
506    /**
507     * <code>Recognizer</code> could not find a match for the utterance.
508     */
509    public final static int EVENT_NO_MATCH = 1;
510
511    /**
512     * <code>Recognizer</code> processed one frame of audio.
513     */
514    public final static int EVENT_INCOMPLETE = 2;
515
516    /**
517     * <code>Recognizer</code> has just been started.
518     */
519    public final static int EVENT_STARTED = 3;
520
521    /**
522     * <code>Recognizer</code> is stopped.
523     */
524    public final static int EVENT_STOPPED = 4;
525
526    /**
527     * Beginning of speech detected.
528     */
529    public final static int EVENT_START_OF_VOICING = 5;
530
531    /**
532     * End of speech detected.
533     */
534    public final static int EVENT_END_OF_VOICING = 6;
535
536    /**
537     * Beginning of utterance occured too soon.
538     */
539    public final static int EVENT_SPOKE_TOO_SOON = 7;
540
541    /**
542     * Recognition match detected.
543     */
544    public final static int EVENT_RECOGNITION_RESULT = 8;
545
546    /**
547     * Timeout occured before beginning of utterance.
548     */
549    public final static int EVENT_START_OF_UTTERANCE_TIMEOUT = 9;
550
551    /**
552     * Timeout occured before speech recognition could complete.
553     */
554    public final static int EVENT_RECOGNITION_TIMEOUT = 10;
555
556    /**
557     * Not enough samples to process one frame.
558     */
559    public final static int EVENT_NEED_MORE_AUDIO = 11;
560
561    /**
562     * More audio encountered than is allowed by 'swirec_max_speech_duration'.
563     */
564    public final static int EVENT_MAX_SPEECH = 12;
565
566    /**
567     * Produce a displayable string from an <code>advance</code> event.
568     * @param event
569     * @return String representing the event.
570     */
571    public static String eventToString(int event) {
572        switch (event) {
573            case EVENT_INVALID:
574                return "EVENT_INVALID";
575            case EVENT_NO_MATCH:
576                return "EVENT_NO_MATCH";
577            case EVENT_INCOMPLETE:
578                return "EVENT_INCOMPLETE";
579            case EVENT_STARTED:
580                return "EVENT_STARTED";
581            case EVENT_STOPPED:
582                return "EVENT_STOPPED";
583            case EVENT_START_OF_VOICING:
584                return "EVENT_START_OF_VOICING";
585            case EVENT_END_OF_VOICING:
586                return "EVENT_END_OF_VOICING";
587            case EVENT_SPOKE_TOO_SOON:
588                return "EVENT_SPOKE_TOO_SOON";
589            case EVENT_RECOGNITION_RESULT:
590                return "EVENT_RECOGNITION_RESULT";
591            case EVENT_START_OF_UTTERANCE_TIMEOUT:
592                return "EVENT_START_OF_UTTERANCE_TIMEOUT";
593            case EVENT_RECOGNITION_TIMEOUT:
594                return "EVENT_RECOGNITION_TIMEOUT";
595            case EVENT_NEED_MORE_AUDIO:
596                return "EVENT_NEED_MORE_AUDIO";
597            case EVENT_MAX_SPEECH:
598                return "EVENT_MAX_SPEECH";
599        }
600        return "EVENT_" + event;
601    }
602
603    //
604    // SR_Recognizer methods
605    //
606    private static native void SR_RecognizerStart(int recognizer);
607    private static native void SR_RecognizerStop(int recognizer);
608    private static native int SR_RecognizerCreate();
609    private static native void SR_RecognizerDestroy(int recognizer);
610    private static native void SR_RecognizerSetup(int recognizer);
611    private static native void SR_RecognizerUnsetup(int recognizer);
612    private static native boolean SR_RecognizerIsSetup(int recognizer);
613    private static native String SR_RecognizerGetParameter(int recognizer, String key);
614    private static native int SR_RecognizerGetSize_tParameter(int recognizer, String key);
615    private static native boolean SR_RecognizerGetBoolParameter(int recognizer, String key);
616    private static native void SR_RecognizerSetParameter(int recognizer, String key, String value);
617    private static native void SR_RecognizerSetSize_tParameter(int recognizer,
618            String key, int value);
619    private static native void SR_RecognizerSetBoolParameter(int recognizer, String key,
620            boolean value);
621    private static native void SR_RecognizerSetupRule(int recognizer, int grammar,
622            String ruleName);
623    private static native boolean SR_RecognizerHasSetupRules(int recognizer);
624    private static native void SR_RecognizerActivateRule(int recognizer, int grammar,
625            String ruleName, int weight);
626    private static native void SR_RecognizerDeactivateRule(int recognizer, int grammar,
627            String ruleName);
628    private static native void SR_RecognizerDeactivateAllRules(int recognizer);
629    private static native boolean SR_RecognizerIsActiveRule(int recognizer, int grammar,
630            String ruleName);
631    private static native boolean SR_RecognizerCheckGrammarConsistency(int recognizer,
632            int grammar);
633    private static native int SR_RecognizerPutAudio(int recognizer, byte[] buffer, int offset,
634            int length, boolean isLast);
635    private static native int SR_RecognizerAdvance(int recognizer);
636    // private static native void SR_RecognizerLoadUtterance(int recognizer,
637    //         const LCHAR* filename);
638    // private static native void SR_RecognizerLoadWaveFile(int recognizer,
639    //         const LCHAR* filename);
640    // private static native void SR_RecognizerSetLockFunction(int recognizer,
641    //         SR_RecognizerLockFunction function, void* data);
642    private static native boolean SR_RecognizerIsSignalClipping(int recognizer);
643    private static native boolean SR_RecognizerIsSignalDCOffset(int recognizer);
644    private static native boolean SR_RecognizerIsSignalNoisy(int recognizer);
645    private static native boolean SR_RecognizerIsSignalTooQuiet(int recognizer);
646    private static native boolean SR_RecognizerIsSignalTooFewSamples(int recognizer);
647    private static native boolean SR_RecognizerIsSignalTooManySamples(int recognizer);
648    // private static native void SR_Recognizer_Change_Sample_Rate (size_t new_sample_rate);
649
650
651    //
652    // SR_AcousticState native methods
653    //
654    private static native void SR_AcousticStateReset(int recognizer);
655    private static native void SR_AcousticStateSet(int recognizer, String state);
656    private static native String SR_AcousticStateGet(int recognizer);
657
658
659    //
660    // SR_Grammar native methods
661    //
662    private static native void SR_GrammarCompile(int grammar);
663    private static native void SR_GrammarAddWordToSlot(int grammar, String slot,
664            String word, String pronunciation, int weight, String tag);
665    private static native void SR_GrammarResetAllSlots(int grammar);
666    // private static native void SR_GrammarAddNametagToSlot(int grammar, String slot,
667    // const struct SR_Nametag_t* nametag, int weight, String tag);
668    private static native void SR_GrammarSetupVocabulary(int grammar, int vocabulary);
669    // private static native void SR_GrammarSetupModels(int grammar, SR_AcousticModels* models);
670    private static native void SR_GrammarSetupRecognizer(int grammar, int recognizer);
671    private static native void SR_GrammarUnsetupRecognizer(int grammar);
672    // private static native void SR_GrammarGetModels(int grammar,SR_AcousticModels** models);
673    private static native int SR_GrammarCreate();
674    private static native void SR_GrammarDestroy(int grammar);
675    private static native int SR_GrammarLoad(String filename);
676    private static native void SR_GrammarSave(int grammar, String filename);
677    // private static native void SR_GrammarSetDispatchFunction(int grammar,
678    //         const LCHAR* name, void* userData, SR_GrammarDispatchFunction function);
679    // private static native void SR_GrammarSetParameter(int grammar, const
680    //         LCHAR* key, void* value);
681    // private static native void SR_GrammarSetSize_tParameter(int grammar,
682    //         const LCHAR* key, size_t value);
683    // private static native void SR_GrammarGetParameter(int grammar, const
684    //         LCHAR* key, void** value);
685    // private static native void SR_GrammarGetSize_tParameter(int grammar,
686    //         const LCHAR* key, size_t* value);
687    // private static native void SR_GrammarCheckParse(int grammar, const LCHAR*
688    //         transcription, SR_SemanticResult** result, size_t* resultCount);
689    private static native void SR_GrammarAllowOnly(int grammar, String transcription);
690    private static native void SR_GrammarAllowAll(int grammar);
691
692
693    //
694    // SR_Vocabulary native methods
695    //
696    // private static native int SR_VocabularyCreate();
697    private static native int SR_VocabularyLoad();
698    // private static native void SR_VocabularySave(SR_Vocabulary* self,
699    //         const LCHAR* filename);
700    // private static native void SR_VocabularyAddWord(SR_Vocabulary* self,
701    //         const LCHAR* word);
702    // private static native void SR_VocabularyGetLanguage(SR_Vocabulary* self,
703    //         ESR_Locale* locale);
704    private static native void SR_VocabularyDestroy(int vocabulary);
705    private static native String SR_VocabularyGetPronunciation(int vocabulary, String word);
706
707
708    //
709    // SR_RecognizerResult native methods
710    //
711    private static native byte[] SR_RecognizerResultGetWaveform(int recognizer);
712    private static native int SR_RecognizerResultGetSize(int recognizer);
713    private static native int SR_RecognizerResultGetKeyCount(int recognizer, int nbest);
714    private static native String[] SR_RecognizerResultGetKeyList(int recognizer, int nbest);
715    private static native String SR_RecognizerResultGetValue(int recognizer,
716            int nbest, String key);
717    // private static native void SR_RecognizerResultGetLocale(int recognizer, ESR_Locale* locale);
718}
719