00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024  
00025 
00026 #ifndef VOCE_H
00027 #define VOCE_H
00028 
00029 
00030 
00031 
00032 
00033 
00034 #include <jni.h>
00035 #include <iostream>
00036 #include <string>
00037 
00039 namespace voce
00040 {
00041 #ifdef WIN32
00042 const std::string pathSeparator = ";";
00043 #else
00044 const std::string pathSeparator = ":";
00045 #endif
00046 
00048         namespace internal
00049         {
00051                 JNIEnv* gEnv = NULL;
00052 
00054                 JavaVM *gJVM = NULL;
00055 
00057                 jclass gClass = NULL;
00058 
00061                 jmethodID gInitID = NULL;
00062                 jmethodID gDestroyID = NULL;
00063                 jmethodID gSynthesizeID = NULL;
00064                 jmethodID gStopSynthesizingID = NULL;
00065                 jmethodID gGetRecognizerQueueSizeID = NULL;
00066                 jmethodID gPopRecognizedStringID = NULL;
00067                 jmethodID gSetRecognizerEnabledID = NULL;
00068                 jmethodID gIsRecognizerEnabledID = NULL;
00069 
00071                 const std::string gClassName = "voce/SpeechInterface";
00072 
00075                 void log(const std::string& msgType, const std::string& msg)
00076                 {
00077                         std::cout << "[Voce";
00078 
00079                         if (std::string("") != msgType)
00080                         {
00081                                 std::cout << " " << msgType;
00082                         }
00083 
00084                         std::cout << "] " << msg << std::endl;
00085                 }
00086 
00089                 jmethodID loadJavaMethodID(const std::string& functionName, 
00090                         const std::string& functionSignature)
00091                 {
00092                         if (!gEnv)
00093                         {
00094                                 log("ERROR", "Method ID cannot be found for function: " 
00095                                         + functionName + " before initialization.");
00096                                 return 0;
00097                         }
00098 
00099                         
00100                         
00101                         
00102                         
00103                         
00104                         
00105                         
00106                         
00107                         
00108                         
00109                         
00110                         
00111                         jmethodID methodID = gEnv->GetStaticMethodID(gClass, 
00112                                 functionName.c_str(), functionSignature.c_str());
00113 
00114                         if (0 == methodID)
00115                         {
00116                                 log("ERROR", "Invalid Java method ID requested for: " 
00117                                         + functionName + ".  Function call ignored.");
00118                                 return 0;
00119                         }
00120 
00121                         return methodID;
00122                 }
00123         }
00124 
00132         void init(const std::string& vocePath, bool initSynthesis, 
00133                 bool initRecognition, const std::string& grammarPath, 
00134                 const std::string& grammarName)
00135         {
00136                 
00137                 JavaVMInitArgs vm_args;
00138                 memset(&vm_args, 0, sizeof(vm_args));
00139                 vm_args.version = JNI_VERSION_1_4;
00140 
00141                 long status = 0;
00142 
00143                 
00144                 
00145                 if (initRecognition)
00146                 {
00147                         vm_args.nOptions = 2;
00148 
00149                         
00150                         
00151                         
00152                         JavaVMOption options[2];
00153 
00154                         
00155                         std::string classPathString = "-Djava.class.path=";
00156                         classPathString += vocePath;
00157                         classPathString += "/voce.jar";
00158                         char s[1024];
00159                         sprintf(s, classPathString.c_str());
00160                         options[0].optionString = s;
00161                         options[0].extraInfo = NULL;
00162 
00163                         
00164                         options[1].optionString = "-Xmx256m";
00165                         options[1].extraInfo = NULL;
00166                         
00167                         
00168                         vm_args.options = options;
00169                         
00170 
00171                         
00172                         status = JNI_CreateJavaVM(&internal::gJVM, 
00173                                 (void**)&internal::gEnv, &vm_args);
00174                 }
00175                 else
00176                 {
00177                         vm_args.nOptions = 1;
00178 
00179                         
00180                         
00181                         
00182                         JavaVMOption options[1];
00183 
00184                         
00185                         std::string classPathString = "-Djava.class.path=";
00186                         classPathString += vocePath;
00187                         classPathString += "/voce.jar";
00188                         char s[1024];
00189                         sprintf(s, classPathString.c_str());
00190                         options[0].optionString = s;
00191                         options[0].extraInfo = NULL;
00192                         
00193                         
00194                         vm_args.options = options;
00195                         
00196 
00197                         
00198                         status = JNI_CreateJavaVM(&internal::gJVM, 
00199                                 (void**)&internal::gEnv, &vm_args);
00200                 }
00201 
00202                 if (status < 0)
00203                 {
00204                         internal::log("ERROR", "Java virtual machine cannot be created");
00205                         return;
00206                 }
00207 
00208                 internal::log("", "Java virtual machine created");
00209 
00210                 
00211                 jclass c = internal::gEnv->FindClass(internal::gClassName.c_str());
00212 
00213                 if (0 == c)
00214                 {
00215                         internal::log("ERROR", "The requested Java class: " 
00216                                 + internal::gClassName + " could not be found.  \
00217 Make sure the class path correctly points to the Voce classes.");
00218                         return;
00219                 }
00220 
00221                 
00222                 
00223                 internal::gClass = (jclass)internal::gEnv->NewGlobalRef(c);
00224 
00225                 
00226                 
00227                 internal::gInitID = internal::loadJavaMethodID("init", 
00228                         "(Ljava/lang/String;ZZLjava/lang/String;Ljava/lang/String;)V");
00229                 internal::gDestroyID = internal::loadJavaMethodID("destroy", "()V");
00230                 internal::gSynthesizeID = internal::loadJavaMethodID("synthesize", 
00231                         "(Ljava/lang/String;)V");
00232                 internal::gStopSynthesizingID = internal::loadJavaMethodID(
00233                         "stopSynthesizing", "()V");
00234                 internal::gGetRecognizerQueueSizeID = internal::loadJavaMethodID(
00235                         "getRecognizerQueueSize", "()I");
00236                 internal::gPopRecognizedStringID = internal::loadJavaMethodID(
00237                         "popRecognizedString", "()Ljava/lang/String;");
00238                 internal::gSetRecognizerEnabledID = internal::loadJavaMethodID(
00239                         "setRecognizerEnabled", "(Z)V");
00240                 internal::gIsRecognizerEnabledID = internal::loadJavaMethodID(
00241                         "isRecognizerEnabled", "()Z");
00242 
00243                 
00244                 jstring jStrVocePath = internal::gEnv->NewStringUTF(
00245                         vocePath.c_str());
00246                 jstring jStrGrammarPath = internal::gEnv->NewStringUTF(
00247                         grammarPath.c_str());
00248                 jstring jStrGrammarName = internal::gEnv->NewStringUTF(
00249                         grammarName.c_str());
00250 
00251                 
00252                 internal::gEnv->CallStaticVoidMethod(internal::gClass, 
00253                         internal::gInitID, jStrVocePath, initSynthesis, initRecognition, 
00254                         jStrGrammarPath, jStrGrammarName);
00255         }
00256 
00259         void destroy()
00260         {
00261                 if (!internal::gEnv)
00262                 {
00263                         internal::log("warning", "destroy called before \
00264 initialization.  Request will be ignored.");
00265                         return;
00266                 }
00267 
00268                 
00269                 internal::gEnv->CallStaticVoidMethod(internal::gClass, 
00270                         internal::gDestroyID);
00271 
00272                 
00273                 
00274                 internal::gEnv->DeleteGlobalRef((jobject)internal::gClass);
00275                 internal::gEnv->DeleteGlobalRef((jobject)internal::gInitID);
00276                 internal::gEnv->DeleteGlobalRef((jobject)internal::gDestroyID);
00277                 internal::gEnv->DeleteGlobalRef((jobject)internal::gSynthesizeID);
00278                 internal::gEnv->DeleteGlobalRef(
00279                         (jobject)internal::gStopSynthesizingID);
00280                 internal::gEnv->DeleteGlobalRef(
00281                         (jobject)internal::gGetRecognizerQueueSizeID);
00282                 internal::gEnv->DeleteGlobalRef(
00283                         (jobject)internal::gPopRecognizedStringID);
00284                 internal::gEnv->DeleteGlobalRef(
00285                         (jobject)internal::gSetRecognizerEnabledID);
00286                 internal::gEnv->DeleteGlobalRef(
00287                         (jobject)internal::gIsRecognizerEnabledID);
00288 
00289                 if (internal::gJVM)
00290                 {
00291                         
00292                         internal::gJVM->DestroyJavaVM();
00293                         internal::log("", "Java virtual machine destroyed");
00294                 }
00295         }
00296 
00298         void synthesize(const std::string& message)
00299         {
00300                 if (!internal::gEnv)
00301                 {
00302                         internal::log("warning", "synthesize called before \
00303 initialization.  Request will be ignored.");
00304                 }
00305 
00306                 
00307                 jstring jstr = internal::gEnv->NewStringUTF(message.c_str());
00308 
00309                 
00310                 internal::gEnv->CallStaticVoidMethod(internal::gClass, 
00311                         internal::gSynthesizeID, jstr);
00312         }
00313 
00316         void stopSynthesizing()
00317         {
00318                 if (!internal::gEnv)
00319                 {
00320                         internal::log("warning", "synthesize called before \
00321 initialization.  Request will be ignored.");
00322                 }
00323 
00324                 
00325                 internal::gEnv->CallStaticVoidMethod(internal::gClass, 
00326                         internal::gStopSynthesizingID);
00327         }
00328 
00331         int getRecognizerQueueSize()
00332         {
00333                 if (!internal::gEnv)
00334                 {
00335                         internal::log("warning", "getRecognizerQueueSize called before \
00336 initialization.  Request will be ignored.");
00337                 }
00338 
00339                 
00340                 return internal::gEnv->CallStaticIntMethod(internal::gClass, 
00341                         internal::gGetRecognizerQueueSizeID);
00342         }
00343 
00346         std::string popRecognizedString()
00347         {
00348                 if (!internal::gEnv)
00349                 {
00350                         internal::log("warning", "popRecognizedString called before \
00351 initialization.  Request will be ignored.");
00352                 }
00353 
00354                 
00355                 jstring jstr = (jstring)internal::gEnv->CallStaticObjectMethod(
00356                         internal::gClass, internal::gPopRecognizedStringID);
00357 
00358                 
00359                 
00360 
00361                 
00362                 const char* tempStr = internal::gEnv->GetStringUTFChars(jstr, 0);
00363                 std::string cppStr = tempStr;
00364                 
00365                 internal::gEnv->ReleaseStringUTFChars(jstr, tempStr);
00366 
00367                 return cppStr;
00368         }
00369 
00371         void setRecognizerEnabled(bool e)
00372         {
00373                 if (!internal::gEnv)
00374                 {
00375                         internal::log("warning", "setRecognizerEnabled called before \
00376 initialization.  Request will be ignored.");
00377                 }
00378 
00379                 
00380                 internal::gEnv->CallStaticIntMethod(internal::gClass, 
00381                         internal::gSetRecognizerEnabledID, e);
00382         }
00383 
00385         bool isRecognizerEnabled()
00386         {
00387                 if (!internal::gEnv)
00388                 {
00389                         internal::log("warning", "isRecognizerEnabled called before \
00390 initialization.  Request will be ignored.");
00391                 }
00392 
00393                 
00394                 jboolean b = internal::gEnv->CallStaticBooleanMethod(internal::gClass, 
00395                         internal::gIsRecognizerEnabledID);
00396 
00397                 if (JNI_FALSE == b)
00398                 {
00399                         return false;
00400                 }
00401                 else
00402                 {
00403                         return true;
00404                 }
00405         }
00406 }
00407 
00408 #endif