14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------* 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * grxmlcompile.cpp * 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Copyright 2007, 2008 Nuance Communciations, Inc. * 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the 'License'); * 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * you may not use this file except in compliance with the License. * 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * You may obtain a copy of the License at * 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 * 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software * 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * distributed under the License is distributed on an 'AS IS' BASIS, * 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * See the License for the specific language governing permissions and * 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * limitations under the License. * 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/ 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "ptypes.h" 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <ext/hash_map> 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/fst.h" 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/fstlib.h" 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/arc.h" 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/fst-decl.h" 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/vector-fst.h" 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/arcsort.h" 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/invert.h" 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst-io.h" 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "ESR_Locale.h" 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "LCHAR.h" 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pstdio.h" 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "PFileSystem.h" 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "PANSIFileSystem.h" 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "plog.h" 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pmemory.h" 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "ESR_Session.h" 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_Session.h" 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_Vocabulary.h" 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "srec_arb.h" // for EPSILON_LABEL etc 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <fstream> 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <iostream> 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "tinyxml.h" 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "grxmldoc.h" 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifdef MEMTRACE 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <mcheck.h> 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define OPENFST_ACKNOWLEDGEMENT \ 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project "This tool uses the OpenFst library. \n" \ 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project "Licensed under the Apache License, Version 2.0 (the \"License\");\n" \ 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" you may not use this file except in compliance with the License.\n" \ 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" You may obtain a copy of the License at" \ 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"\n" \ 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" http://www.apache.org/licenses/LICENSE-2.0\n" \ 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"\n" \ 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" Unless required by applicable law or agreed to in writing, software\n" \ 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" distributed under the License is distributed on an \"AS IS\" BASIS,\n" \ 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" \ 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" See the License for the specific language governing permissions and\n" \ 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" limitations under the License.\n" \ 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"\n" \ 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project" This library was developed at Google Research (M. Riley, J. Schalkwyk, W. Skut) and NYU's Courant Institute (C. Allauzen, M. Mohri). It is intended to be comprehensive, flexible, efficient and scale well to large problems. It is an open source project distributed under the Apache license. \n" 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define TINYXML_ACKNOWLEDGEMENT \ 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project "This tool uses the tinyxml library. \n" \ 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"Copyright (c) 2007 Project Admins: leethomason \n" \ 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"The TinyXML software is provided 'as-is', without any express or implied\n" \ 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"warranty. In no event will the authors be held liable for any damages\n" \ 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"arising from the use of this software.\n" \ 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"\n" \ 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"Permission is granted to anyone to use this software for any purpose,\n" \ 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"including commercial applications, and to alter it and redistribute it\n" \ 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"freely, subject to the following restrictions:\n" 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define NUANCE_COPYRIGHT \ 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// grxmlcompile\n" \ 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"//\n" \ 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" \ 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// you may not use this file except in compliance with the License.\n" \ 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// You may obtain a copy of the License at\n" \ 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"//\n" \ 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// http://www.apache.org/licenses/LICENSE-2.0\n" \ 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"//\n" \ 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// Unless required by applicable law or agreed to in writing, software\n" \ 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" \ 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" \ 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// See the License for the specific language governing permissions and\n" \ 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// limitations under the License.\n" \ 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"//\n" \ 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// This program compiles a .grxml grammar into the graphs needed for \n" \ 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// decoding with SREC\n" \ 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project"// \n" 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_LINE_LENGTH 256 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_PATH_NAME 512 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_PRONS_LENGTH 1024 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SILENCE_PREFIX_WORD "-pau-" 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SILENCE_SUFFIX_WORD "-pau2-" 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SLOT_SUFFIX "__" 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SLOT_PREFIX "__" 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define MAX_NUM_SLOTS 12 /* must agree with srec_context.h */ 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define EXTRA_EPSILON_LABEL 39999 // must be higher than the number of models 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEFAULT_WB_COST 40 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEFAULT_WB_COST_STR "40" 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define SLOT_COUNTER_OFFSET 30000 // must be higher than the number of models 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define NOISE_PHONEME_CODE 'J' 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int debug = 0; 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int verbose = 0; 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectusing namespace std; 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode make_openfst_graphs(GRXMLDoc* pDoc, /* for metas */ 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const std::string& grxmlBasename, 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* vocabFilename, 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* cfstFilename, 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* modelmapFilename); 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectconst char* showline(const char* fn, int line_num) 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project static char line[8096] = { 0 }; 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int line_count = 0; 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ifstream strm(fn); 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (strm && strm.getline(line, sizeof(line))) 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(line_count++ == line_num) break; 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return &line[0]; 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstd::string ExtractFileName(const std::string& full) 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string::size_type idx = full.find_last_of("/"); 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (idx != std::string::npos) 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return full.substr(idx+1); 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return full; 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*-----------------------------------------------------------------------* 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------------*/ 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint usage_error(const char* prgname) 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project printf("USAGE: -par <par file> -grxml <grxml grammar file> -vocab <dictionary file (.ok)> [-outdir <output directory>]\n"); 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (int)ESR_INVALID_ARGUMENT; 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint main(int argc, char* argv[]) 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode status = ESR_SUCCESS; 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *parfile = NULL; 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *grxmlfile = NULL; 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *cmdline_vocfile = NULL; 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string outdir("."); // default output dir is current directory 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* for now, assume char and LCHAR are the same, else fail to compile! */ 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { char zzz[ 1 - (sizeof(LCHAR)!=sizeof(char))]; zzz[0] = 0; } 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifdef MEMTRACE 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mtrace(); 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if defined(GRXMLCOMPILE_PRINT_ACKNOWLEDGEMENT) 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << OPENFST_ACKNOWLEDGEMENT <<std::endl; 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << TINYXML_ACKNOWLEDGEMENT <<std::endl; 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << NUANCE_COPYRIGHT <<std::endl; 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Process all XML files given on command line 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(argc<5){ 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return usage_error(argv[0]); 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(int i=1;i<argc;i++) 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!strcmp(argv[i],"-grxml")) 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project grxmlfile = argv[++i]; 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if(!strcmp(argv[i],"-debug")) 1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project debug++; 1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if(!strcmp(argv[i],"-verbose")) 1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project verbose++; 1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if(!strcmp(argv[i],"-par") || !strcmp(argv[i],"-parfile")) 1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project parfile = argv[++i]; 1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if(!strcmp(argv[i],"-vocab")) 1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmdline_vocfile = argv[++i]; 1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if(!strcmp(argv[i],"-outdir")) 1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project outdir = std::string(argv[++i]); 1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else { 1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project printf("error_usage: argument [%s]\n", argv[i]); 1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return usage_error(argv[0]); 2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (int)ESR_INVALID_ARGUMENT; 2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project //process_xml( std::string(grxmlfile), parfile ); 2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string filename = std::string(grxmlfile); 2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*************************** 2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project process xml 2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ***************************/ 2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "processing [" << filename << "] ..." << endl; 2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project TiXmlDocument node; 2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool bLoadedOK = node.LoadFile( filename.c_str() ); 2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!bLoadedOK || node.Error()) { 2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: while creating TiXmlDocument from " << filename << std::endl; 2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: " << node.Error() << " id " << node.ErrorId() << " row " << node.ErrorRow() << " col " << node.ErrorCol() << std::endl; 2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: " << node.ErrorDesc() << std::endl; 2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: near " << showline( filename.c_str(), node.ErrorRow()) << std::endl; 2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (int)ESR_INVALID_ARGUMENT; 2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // ************************************************* 2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Parse the file into a DOM object and create word graph 2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // 2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project GRXMLDoc *doc = new (GRXMLDoc); 2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string filenameNoPath = ExtractFileName(filename); 2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project doc->parseGrammar( node, filenameNoPath ); // THE PARSING AND NETWORK BUILD HAPPENS IN HERE 2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /************************ 2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project end of xml processing 2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ************************/ 2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Create grammar network files. Use prefix of input file for output. 2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string s = filename; 2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string grxmlbase = outdir + "/" + ExtractFileName(grxmlfile); 2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project unsigned int p1 = grxmlbase.find_last_of("."); 2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if ( p1 != string::npos ) 2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project grxmlbase.assign( grxmlbase, 0, p1); 2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string newName; 2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project newName = grxmlbase + ".map"; 2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project doc->writeMapFile( newName ); 2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project newName = grxmlbase + ".script"; 2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project doc->writeScriptFile( newName ); 2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project doc->writeGraphFiles( grxmlbase, false ); 2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // 2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // SR initialization 2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // 2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char vocfile[MAX_PATH_NAME]; 2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char cfstfile[MAX_PATH_NAME]; 2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char modelmapfile[MAX_PATH_NAME]; 2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t len; 2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PMemInit(); 2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project printf("info: Using parfile %s\n",parfile); 2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project status = SR_SessionCreate((const LCHAR*) parfile); 2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // status = SR_SessionCreate ( parfile ); 2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if ( status != ESR_SUCCESS ) { 2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LPRINTF("Error: SR_SessionCreate(%s) %s\n", parfile, ESR_rc2str(status)); 2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (int)status; 2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // vocfile 2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(cmdline_vocfile) { 2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project strcpy( vocfile, cmdline_vocfile); 2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len = MAX_PATH_NAME; 2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_SessionGetLCHAR ( L("cmdline.vocabulary"), (LCHAR*)vocfile, &len ); 2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // skip PrefixWithBaseDirectory(), 'tis done inside SR_VocabularyLoad() 2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project printf("info: Using dictionary %s\n",vocfile); 2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // modelmapfile 2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len = MAX_PATH_NAME; 2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_SessionGetLCHAR ( L("cmdline.arbfile"), (LCHAR*)modelmapfile, &len); 2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len = MAX_PATH_NAME; 2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project status = ESR_SessionPrefixWithBaseDirectory ( (LCHAR*)modelmapfile, &len); 2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char* p = strrchr(modelmapfile,'/'); 2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!p) p = strrchr(modelmapfile,'\\'); 2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(p) strcpy(p, "/models128x.map"); 2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // cfstfile 2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len = MAX_PATH_NAME; 2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_SessionGetLCHAR ( L("cmdline.arbfile"), (LCHAR*)cfstfile, &len); 2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len = MAX_PATH_NAME; 2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project status = ESR_SessionPrefixWithBaseDirectory ( (LCHAR*)cfstfile, &len); 2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project p = strrchr(cfstfile,'/'); 2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!p) p = strrchr(cfstfile,'\\'); 2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(p) strcpy(p, "/generic.C"); 2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project status = make_openfst_graphs( doc, grxmlbase, (const char*)vocfile, (const char*)cfstfile, (const char*)modelmapfile); 2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(status != ESR_SUCCESS) { 2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LPRINTF("Error: make_openfst_graphs() returned %s\n", ESR_rc2str(status)); 2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* make_openfst_graphs() can sometimes call doc->setMeta() to put 2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Session parameters into the .params file, so writeParamsFile() 3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project should be called after make_openfst_graphs() */ 3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project newName = grxmlbase + ".params"; 3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project doc->writeParamsFile( newName ); 3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // 3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // SR de-initialization 3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // 3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SR_SessionDestroy(); 3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project PMemShutdown(); 3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete doc; 3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (int)status; 3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*-----------------------------------------------------------------* 3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * utils * 3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectbool is_slot_symbol( const char* sym) 3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* p = strstr(sym,SLOT_PREFIX); 3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int len = strlen(sym); 3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(len>4 && !strcmp(sym+len-2,SLOT_SUFFIX) && (p-sym)<len-2) { 3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return true; 3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else 3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint64 StrToId(const char *s, fst::SymbolTable *syms, 3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char *name) 3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int64 n; 3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (syms) { 3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project n = syms->Find(s); 3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (n < 0) { 3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "FstReader: Symbol \"" << s 3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << "\" is not mapped to any integer " << name 3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << ", symbol table = " << syms->Name(); 3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char *p; 3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project n = strtoll(s, &p, 10); 3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (p < s + strlen(s) || n < 0) { 3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "FstReader: Bad " << name << " integer = \"" << s; 3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return n; 3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* FstMergeOLabelsToILabels, FstSplitOLabelsFromILabels 3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project are used to make sure the minimization does not go overboard in pushing 3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project output labels toward the beginning of the graph. When that happens 3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project then the speech recognition decoder fails! */ 3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode FstMergeOLabelsToILabels( fst::StdVectorFst& fst_, int max_ilabels ) 3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc::StateId s = fst_.Start(); 3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (s == fst::kNoStateId) 3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(fst_); 3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s = siter.Value(); 3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&fst_, s); 3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc = aiter.Value(); 3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if( arc.ilabel >= max_ilabels || 3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (float)arc.ilabel + ((float)max_ilabels)*arc.olabel > INT_MAX) { 3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: internal error in FstMergeOLabelsToILabels() " << std::endl; 3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_NOT_IMPLEMENTED; 3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.ilabel = arc.ilabel + max_ilabels * arc.olabel; 3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.olabel = 0; 3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter.SetValue( arc); 3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode FstMergeOLabelsToILabels_GetMax( fst::StdVectorFst& fst_, int& max_ilabel ) 3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fst_.Start() == fst::kNoStateId) return ESR_INVALID_ARGUMENT; 3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(fst_); 3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&fst_, siter.Value()); 3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if( aiter.Value().ilabel > max_ilabel) 3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project max_ilabel = aiter.Value().ilabel; 3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project max_ilabel++; 3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode FstSplitOLabelsFromILabels( fst::StdVectorFst& fst_, int max_ilabels ) 3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc::StateId s = fst_.Start(); 3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (s == fst::kNoStateId) 3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(fst_); 4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s = siter.Value(); 4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&fst_, s); 4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc = aiter.Value(); 4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.olabel = arc.ilabel / max_ilabels; 4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.ilabel = arc.ilabel - arc.olabel*max_ilabels; 4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter.SetValue( arc); 4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* this is to replace the "fake" extra epsilon input labels, which were 4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project put there to disambiguate homonyms */ 4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode FstReplaceILabel( fst::StdVectorFst& fst_, int from_ilabel, int into_ilabel) 4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc::StateId s = fst_.Start(); 4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (s == fst::kNoStateId) 4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(fst_); 4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s = siter.Value(); 4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&fst_, s); 4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc = aiter.Value(); 4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(arc.ilabel == from_ilabel) { 4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.ilabel = into_ilabel; 4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter.SetValue( arc); 4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* this pushes the slot labels forward which gives an opportunity for 4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project multiple instances of the slot to be merged, eg. lookup NAME 4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project vs lookup contact NAME .. if in separate rules, then they will 4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project merge thanks to using 3 arcs for the NAME */ 4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode FstPushSlotLikeOLabels( fst::StdVectorFst& fst_, int myMin, int myMax) 4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode rc = ESR_SUCCESS; 4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project char done_for_state[2*65536]; // hope this is enough! 4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project memset( &done_for_state[0], 0, sizeof(done_for_state)); 4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc::StateId s = fst_.Start(); 4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(fst_); 4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s = siter.Value(); 4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(done_for_state[ s]) continue; 4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project done_for_state[ s]++; 4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&fst_, s); 4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc = aiter.Value(); 4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(arc.olabel >= myMin && arc.olabel < myMax) { 4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc::StateId s2 = arc.nextstate; 4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int slotId = arc.olabel; 4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(verbose) 4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "info: FstPushSlotLikeOLabels() at state " << s << " arc ilabel " << arc.ilabel << " olabel " << arc.olabel << std::endl; 4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.ilabel = EPSILON_LABEL; 4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.olabel = EPSILON_LABEL; 4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc.weight = 0; // zero weight 4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter.SetValue( arc); 4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project done_for_state[ s2]++; 4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter2(&fst_, s2); 4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter2.Done(); aiter2.Next()) { 4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc2 = aiter2.Value(); 4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(arc2.ilabel == WORD_BOUNDARY) { 4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: FstPushSlotLikeOLabels() failing, there could be confusion between the slot (hack-pron) and a real-pron, the slot olabel may have been pushed by earlier fst operations!" << std::endl; 4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_INVALID_STATE; 4804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else 4814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc2.ilabel = EPSILON_LABEL; 4824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project arc2.olabel = slotId; 4834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter2.SetValue( arc2); 4844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* check */ 4904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int *num_pclg_arcs_using_slot = new int[myMax]; 4914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(i=0;i<myMax;i++) num_pclg_arcs_using_slot[i] = 0; 4924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(fst_); 4934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 4944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s = siter.Value(); 4954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&fst_, s); 4974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 4984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc = aiter.Value(); 4994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(arc.olabel >= myMin && arc.olabel < myMax) 5004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_pclg_arcs_using_slot[arc.olabel]++; 5014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(i=0; i<myMax; i++) { 5044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(num_pclg_arcs_using_slot[i] > 1) { 5054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: SREC will not support multiply referred slots." << std::endl; 5064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: Consider re-working your grammar to merge the references into one rule" << std::endl; 5074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: or use two different slots" << std::endl; 5084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_NOT_SUPPORTED; 5094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete [] num_pclg_arcs_using_slot; 5124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 5144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 5154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* gets the range of slot numbers, myMin inclusive, myMax is exclusive */ 5174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid get_slot_olabel_range( const fst::SymbolTable* syms, int* myMin, int* myMax) 5194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 5204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // assumes slots are at the top of the symbol table 5214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::SymbolTableIterator iter( *syms); 5224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *myMin = *myMax = 0; 5234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(iter.Reset(); !iter.Done(); iter.Next() ) { 5244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* sym = iter.Symbol(); 5254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if ( is_slot_symbol( sym)) { 5264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(! (*myMin)) *myMin = iter.Value(); 5274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *myMax = iter.Value()+1; 5284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 5314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* SLOT_COUNTER_OFFSET 5334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project The cfst is used to turn phonemes into acoustic models, but we're using 5344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project special phonemes for the slots, and must here add those as pass through 5354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project in the Cfst, meaning that the slot marker must be unchanged after 5364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project composition. To do that we find the places in the Cfst where silence is 5374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project used, and put the slot marker arcs in parallel. This also causes the 5384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project models before the slot to assume silence to the right, and the models after 5394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project the slot to assume silence to the left, both of which are reasonable */ 5404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode FstAddSlotMarkersToCFst( fst::StdVectorFst& cfst_, int myMin, int myMax) 5424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 5434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int num_silence_arcs_in_cfst = 0; 5444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int mimicPhonemeCode = SILENCE_CODE; 5454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc::StateId s = cfst_.Start(); 5474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (s == fst::kNoStateId) 5484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 5494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (fst::StateIterator< fst::StdVectorFst> siter(cfst_); 5504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); siter.Next()) { 5514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project s = siter.Value(); 5524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(fst::MutableArcIterator<fst::StdVectorFst> aiter(&cfst_, s); 5544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); aiter.Next()) { 5554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdArc arc = aiter.Value(); 5564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if( arc.olabel == mimicPhonemeCode) { 5574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_silence_arcs_in_cfst++; 5584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(int i=myMin; i<myMax; i++) 5594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cfst_.AddArc( s, fst::StdArc(SLOT_COUNTER_OFFSET+i /*model*/, 5604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SLOT_COUNTER_OFFSET+i /*phoneme*/, 0.0, arc.nextstate)); 5614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::ArcSort(&cfst_, fst::StdOLabelCompare()); 5654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!num_silence_arcs_in_cfst) 5664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 5674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 5684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_SUCCESS; 5694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 5704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* 5724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * make the graphs used by the recognition engine during the search. 5734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 5744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode make_openfst_graphs( GRXMLDoc* pDoc, 5764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const std::string& grxmlBasename, 5774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* vocabFilename, 5784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* cfstFilename, 5794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* modelmapFilename) 5804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 5814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SR_Vocabulary *vocab = 0; 5824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode rc; 5834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst l_fst; // .L file, created from the .map and .ok 5854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int stateSt, stateEn; 5874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t len; 5884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool do_skip_interword_silence = false; 5894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project hash_map<string,int> homonym_count; 5904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int word_penalty = 0; 5914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = SR_VocabularyLoad(vocabFilename, &vocab); 5934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc != ESR_SUCCESS) { 5944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "Error: " << ESR_rc2str(rc) << endl; 5954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; // goto CLEANUP; 5964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 5974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 5984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string word_penalty_str; 5994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if( pDoc->findMeta(std::string("word_penalty"),word_penalty_str)) 6004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project word_penalty = atoi((const char *)word_penalty_str.c_str()); 6014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else { 6024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = ESR_SessionGetInt( L("CREC.Recognizer.wordpen"), &word_penalty); 6034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(rc != ESR_SUCCESS) 6044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project word_penalty = DEFAULT_WB_COST; 6054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project word_penalty_str = DEFAULT_WB_COST_STR; 6064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pDoc->setMeta( std::string("word_penalty"), word_penalty_str) ; 6074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "using word_penalty " << word_penalty << endl; 6084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string do_skip_interword_silence_str; 6114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if( pDoc->findMeta(std::string("do_skip_interword_silence"), do_skip_interword_silence_str)) 6124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project do_skip_interword_silence = ((do_skip_interword_silence_str != "true") ? false : true); 6134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 6154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * read the .map and .omap created from grxmlcompiler classes * 6164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 6174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string omapFilename = grxmlBasename + std::string(".omap"); 6194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string imapFilename = grxmlBasename + std::string(".map"); 6204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: reading word symbols " << imapFilename << endl; 6224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::SymbolTable *word_syms = fst::SymbolTable::ReadText(imapFilename); 6234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!word_syms) { 6244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "error: reading word_syms" << endl; 6254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 6264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: reading parser symbols " << omapFilename << endl; 6284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::SymbolTable *prsr_syms = fst::SymbolTable::ReadText(omapFilename); 6294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!prsr_syms) { 6304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "error: reading prsr_syms" << endl; 6314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 6324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: reading model symbols " << modelmapFilename << endl; 6344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::SymbolTable *model_syms = fst::SymbolTable::ReadText(modelmapFilename); 6354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!prsr_syms) { 6364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "error: reading prsr_syms" << endl; 6374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 6384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int max_model_sym = 0; 6404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* if(1) { 6414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::SymbolTableIterator iter( *model_syms); 6424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(iter.Reset(); !iter.Done(); iter.Next() ) max_model_sym++; */ 6434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 6454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * create the .L pronunciations transducer * 6464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 6474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Adds state 0 to the initially empty FST and make it the start state. 6494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateSt = l_fst.AddState(); 6504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateEn = l_fst.AddState(); 6514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.SetStart(stateSt); // arg is state ID 6524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.SetFinal(stateEn, 0.0); // 1st arg is state ID, 2nd arg weight 6534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateEn, fst::StdArc(EPSILON_LABEL,EPSILON_LABEL,0.0,stateSt)); 6544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int num_slots = 0; 6564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::SymbolTableIterator iter( *word_syms); 6574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(iter.Reset(); !iter.Done(); iter.Next() ) { 6584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ESR_ReturnCode rc; 6594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LCHAR prons[MAX_PRONS_LENGTH]; 6604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const char* phrase = iter.Symbol(); 6614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int wordId = iter.Value(); 6624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool wordId_is_silence = false; 6634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool wordId_is_slot = false; 6644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* script or scope marker, skip it */ 6654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* if( is_scope_marker( phrase) || is_script_marker(phrase)) 6664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; */ 6674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* epsilon */ 6684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!strcmp( phrase, SILENCE_PREFIX_WORD) 6694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project || !strcmp(phrase,SILENCE_SUFFIX_WORD)) 6704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wordId_is_silence = true; 6714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if( !strcmp( phrase, "eps") && wordId == 0) 6724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; 6734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* rule markers */ 6744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if( strstr( phrase, ".grxml@")) 6754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; 6764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* script markers */ 6774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if( phrase[0]=='_' && strspn(phrase+1,"0123456789")==strlen(phrase+1)) 6784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; 6794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else if(is_slot_symbol(phrase)) { 6804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "SLOT>> " << phrase << endl; 6814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wordId_is_slot = true; 6824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_slots++; 6834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(num_slots > MAX_NUM_SLOTS) { 6864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: SREC may have trouble with this many slots! (" << num_slots << ")" << std::endl; 6874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // return ESR_NOT_SUPPORTED; 6884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 6894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 6904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(wordId_is_slot) { 6914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int stateP = stateSt, statePp1; 6924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* with 2 arcs, we have a better chance to merge the slot if used from 6934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project different parts of the grammar, see FstPushSlotLikeOLabels elsewhere */ 6944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project statePp1 = l_fst.AddState(); 6954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( wordId+SLOT_COUNTER_OFFSET, wordId, 0.0, statePp1)); 6964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateP = statePp1; 6974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project statePp1 = l_fst.AddState(); 6984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( wordId+SLOT_COUNTER_OFFSET, EPSILON_LABEL, 0.0, statePp1)); 6994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateP = statePp1; 7004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( WORD_BOUNDARY, EPSILON_LABEL, 0.0, stateEn)); 7014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 7024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project size_t len_used; 7034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LCHAR *pron = 0, *p; 7044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* word is ok, get the pron */ 7054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len = MAX_PRONS_LENGTH; 7064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = SR_VocabularyGetPronunciation(vocab, phrase, prons, &len); 7074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (rc != ESR_SUCCESS) { 7084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LPRINTF( "ERROR: SR_VocabularyGetPronunciation(*,%s,*,*) returned %s\n", phrase, ESR_rc2str(rc)); 7094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SR_VocabularyDestroy(vocab); 7104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 7114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(len_used=0; len_used<len; ) { 7134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project pron = &prons[0]+len_used; 7144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project len_used += LSTRLEN(pron)+1; 7154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if( *pron == 0) break; 7164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int stateP = stateSt, statePp1; 7174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int olabel = wordId; 7184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LPRINTF("%s : %s\n", phrase, pron); 7194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* main pronunciation */ 7204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(p=pron; *p; p++) { 7214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project statePp1 = l_fst.AddState(); 7224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(*p == OPTSILENCE_CODE) { 7234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( SILENCE_CODE, olabel, 0.0, statePp1)); 7244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( EPSILON_LABEL, olabel, 0.0, statePp1)); 7254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 7264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( *p, olabel, 0.0, statePp1)); 7274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateP = statePp1; 7294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project olabel = EPSILON_LABEL; 7304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* add epsilons if this is a homonym */ 7324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project string pron_string = pron; 7334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project hash_map<string,int>::const_iterator it = homonym_count.find( pron_string); 7344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(it == homonym_count.end()) { 7354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project homonym_count[ pron_string] = 0; 7364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 7374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project homonym_count[ pron_string] = homonym_count[ pron_string]+1; 7384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int extra_epsilons_needed = homonym_count[ pron_string] ; 7404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(wordId_is_silence) extra_epsilons_needed = 0; 7414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for(int i=0;i<extra_epsilons_needed;i++) { 7424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project statePp1 = l_fst.AddState(); 7434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( EXTRA_EPSILON_LABEL, olabel, 0.0, statePp1)); 7444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateP = statePp1; 7454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* add optional silence after each word */ 7474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!do_skip_interword_silence && !wordId_is_silence && !wordId_is_slot) { 7484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project statePp1 = l_fst.AddState(); 7494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( SILENCE_CODE, EPSILON_LABEL, 0.0, statePp1)); 7504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(statePp1, fst::StdArc( WORD_BOUNDARY, EPSILON_LABEL, 0.0, stateEn)); 7514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( WORD_BOUNDARY, EPSILON_LABEL, 0.0, stateEn)); 7524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else if(wordId_is_silence && !strcmp(phrase, SILENCE_SUFFIX_WORD)) { 7534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* SILENCE_SUFFIX_WORD does not need a terminal .wb */ 7544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( EPSILON_LABEL, EPSILON_LABEL, 0.0, stateEn)); 7554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 7564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project l_fst.AddArc(stateP, fst::StdArc( WORD_BOUNDARY, EPSILON_LABEL, 0.0, stateEn)); 7574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } // loop over multiple prons 7594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } // slot vs non-slot 7604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } /* .map (word_syms) iterator */ 7614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string lfstFilename = grxmlBasename + ".L"; 7634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // We can save this FST to a file with: 7644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) l_fst.Write(lfstFilename.c_str()); 7654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 7674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * read the .P.txt created from grxmlcompiler classes * 7684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 7694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string ptxtFilename = grxmlBasename + std::string(".P.txt"); 7714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::ifstream istrm(ptxtFilename.c_str()); 7724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(!istrm) { 7734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cerr << "error: reading ptxtFilename" << endl; 7744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 7754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 7764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: reading parser from text " << ptxtFilename << endl; 7784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::FstReader<fst::StdArc> reader( istrm, ptxtFilename, word_syms, prsr_syms, 7794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*state_syms*/ NULL, 7804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*acceptor*/ false, 7814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*ikeep*/ false, 7824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*okeep*/ false, 7834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*nkeep*/ false); 7844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // .P file, created from the .P.txt and .omap 7854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const fst::StdVectorFst& p_fst = reader.Fst(); 7864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 7884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * make the helper FSTs * 7894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 7904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 7914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: creating helper fsts" << endl; 7924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst prefix_fst; 7934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst suffix_fst; 7944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst eps_fst; 7954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // int eps_word = StrToId("eps", word_syms, "arc ilabel"); 7964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int pau_word = StrToId(SILENCE_PREFIX_WORD, word_syms, "arc ilabel"); 7974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int pau2_word = StrToId(SILENCE_SUFFIX_WORD, word_syms, "arc ilabel"); 7984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(pau_word < 0 || pau2_word < 0) 7994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ESR_INVALID_ARGUMENT; 8004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateSt = prefix_fst.AddState(); 8024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateEn = prefix_fst.AddState(); 8034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prefix_fst.SetStart(stateSt); // arg is state ID 8044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prefix_fst.SetFinal(stateEn, 0.0); // 1st arg is state ID, 2nd arg weight 8054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prefix_fst.AddArc(stateSt, fst::StdArc(pau_word, pau_word, 0.0, stateEn)); 8064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateSt = suffix_fst.AddState(); 8084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateEn = suffix_fst.AddState(); 8094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project suffix_fst.SetStart(stateSt); // arg is state ID 8104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project suffix_fst.SetFinal(stateEn, 0.0); // 1st arg is state ID, 2nd arg weight 8114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project suffix_fst.AddArc(stateSt, fst::StdArc(pau2_word, pau2_word, 0.0, stateEn)); 8124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateSt = eps_fst.AddState(); 8144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project stateEn = stateSt; // stateEn = eps_fst.AddState(); 8154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project eps_fst.SetStart(stateSt); // arg is state ID 8164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project eps_fst.SetFinal(stateEn, 0.0); // 1st arg is state ID, 2nd arg weight 8174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // eps_fst.AddArc(stateSt, fst::StdArc(eps_word, eps_word, 0.0, stateEn)); 8184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 8204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * make Grev2.det.txt * 8214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 8224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: creating reverse g fst" << endl; 8234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst g_fst = p_fst; // this is a copy!! 8244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst grev_fst; // reversed 8254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst grev_min_fst; // eps removed and minimized 8264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst grev_det_fst; 8274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Project(&g_fst, fst::PROJECT_INPUT); 8294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) g_fst.Write( grxmlBasename + ".G"); 8304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Reverse( g_fst, &grev_fst); 8314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) grev_fst.Write( grxmlBasename + ".Grev"); 8324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::RmEpsilon( &grev_fst, /*connect?*/ true ); 8334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) grev_fst.Write( grxmlBasename + ".Grevrme"); 8344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Determinize(grev_fst, &grev_det_fst); 8354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) grev_det_fst.Write( grxmlBasename + ".Grevrmedet"); 8364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(1) fst::Minimize(&grev_det_fst); 8374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) grev_det_fst.Write( grxmlBasename + ".Grevrmedetmin"); 8384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Concat( &eps_fst, grev_det_fst); 8394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project grev_det_fst = eps_fst; 8404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) grev_det_fst.Write( grxmlBasename + ".Grevrmedetmin2"); 8414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string grevFilename = grxmlBasename + std::string(".Grev2.det.txt"); 8424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: writing reverse G fst as text " << grevFilename << endl; 8444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ostream* ostrm1 = new ofstream( grevFilename.c_str(), ios_base::out); 8454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::FstPrinter<fst::StdArc> printer1( grev_det_fst, 8464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project word_syms, word_syms, 8474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project NULL, /*acceptor?*/ true); 8484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project printer1.Print( ostrm1, grevFilename); 8494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete ostrm1; 8504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 8524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * make PCLG.txt * 8534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 8544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst* c_fst; 8564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst lg_fst; 8574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst clg_fst; 8584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::StdVectorFst clg_det_fst; 8594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: reading model fst " << cfstFilename << endl; 8614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c_fst = fst::StdVectorFst::Read( cfstFilename); 8624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int slot_olabel_min=0, slot_olabel_max=0; // [min,max) .. ie excludes max 8644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project get_slot_olabel_range( word_syms, &slot_olabel_min, &slot_olabel_max); 8654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(slot_olabel_max > MAX_NUM_SLOTS) 8664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: SREC may have trouble with this many slots! (" << slot_olabel_max << ")" << std::endl; 8674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* add slot markers as if they were silence phonemes, this makes the context 8694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for them as if the slot were silence, which is reasonable, although another 8704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project reasonable thing would be to allow all contexts. Adding the true context 8714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project only would add complexity and slow down word addition too much. */ 8724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = FstAddSlotMarkersToCFst( *c_fst, slot_olabel_min, slot_olabel_max); 8744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(rc) return rc; 8754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Concat( &g_fst, suffix_fst); 8774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Concat( &prefix_fst, g_fst); 8784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) prefix_fst.Write( grxmlBasename + ".G2"); 8794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::ComposeOptions copts( /*connect?*/ true); 8804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::ArcSort(&l_fst, fst::StdOLabelCompare()); 8824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::ArcSort(&prefix_fst, fst::StdILabelCompare()); 8834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Compose(l_fst, prefix_fst, &lg_fst, copts); 8854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) lg_fst.Write( grxmlBasename + ".LG"); 8864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::ArcSort(&lg_fst, fst::StdILabelCompare()); 8874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) lg_fst.Write( grxmlBasename + ".LG2"); 8884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::RmEpsilon( &lg_fst, /*connect?*/ true ); 8904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) lg_fst.Write( grxmlBasename + ".LGrme"); 8914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Determinize( lg_fst, &clg_fst); // clg_fst is really lg_det_fst! 8924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) clg_fst.Write( grxmlBasename + ".LGrmedet"); 8934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = FstReplaceILabel( clg_fst, EXTRA_EPSILON_LABEL, EPSILON_LABEL); 8944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Compose( *c_fst, clg_fst, &clg_det_fst, copts); 8954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) clg_det_fst.Write( grxmlBasename + ".CLGrmedet"); 8964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 8974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = FstMergeOLabelsToILabels_GetMax( clg_det_fst, /*int&*/max_model_sym); 8984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(verbose) 8994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: merging into ilabels I=i+" << max_model_sym << "*o" << endl; 9004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = FstMergeOLabelsToILabels( clg_det_fst, max_model_sym); 9014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) clg_det_fst.Write( grxmlBasename + ".CLGrmedet2"); 9024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::Minimize( &clg_det_fst); 9034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) clg_det_fst.Write( grxmlBasename + ".CLGrmedet3"); 9044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(verbose) 9054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cout << "info: splitting from ilabels" << endl; 9064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = FstSplitOLabelsFromILabels( clg_det_fst, max_model_sym); 9074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) clg_det_fst.Write( grxmlBasename + ".CLGrmedet4"); 9084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project rc = FstPushSlotLikeOLabels( clg_det_fst, slot_olabel_min, slot_olabel_max); 9104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(rc != ESR_SUCCESS) 9114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::cout << "Error: FstPushSlotLikeOLabels() failed" << std::endl; 9124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(debug) clg_det_fst.Write( grxmlBasename + ".CLG"); 9134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project std::string pclgFilename = grxmlBasename + ".PCLG.txt"; 9154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ostream* ostrm = new ofstream( pclgFilename.c_str(), ios_base::out); 9164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fst::FstPrinter<fst::StdArc> printer( clg_det_fst, 9174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project model_syms, word_syms, 9184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project NULL, /*acceptor?*/ false); 9194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project printer.Print( ostrm, pclgFilename); 9204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete ostrm; 9214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete c_fst; 9234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete word_syms; word_syms = NULL; 9244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete prsr_syms; prsr_syms = NULL; 9254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete model_syms; model_syms = NULL; 9264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /*-----------------------------------------------------------------* 9284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * cleanup * 9294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *-----------------------------------------------------------------*/ 9304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if(vocab) { 9324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SR_VocabularyDestroy(vocab); 9334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project vocab = NULL; 9344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 9354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return rc; 9374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 9394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 9404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 941