/*---------------------------------------------------------------------------*
* vocab.cpp *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the 'License'); *
* you may not use this file except in compliance with the License. *
* *
* You may obtain a copy of the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#include <string>
#include <iostream>
#include <stdexcept>
#include "ESR_Locale.h"
#include "LCHAR.h"
#include "pstdio.h"
#include "ESR_Session.h"
#include "SR_Vocabulary.h"
#include "vocab.h"
#define MAX_LINE_LENGTH 256
#define MAX_PRONS_LENGTH 1024
#define DEBUG 0
#define GENERIC CONTEXT "#"
Vocabulary::Vocabulary( std::string const & vocFileName )
{
ESR_ReturnCode rc;
rc = SR_VocabularyLoad(vocFileName.c_str(), &m_hVocab);
if (rc != ESR_SUCCESS)
{
std::cout << "Error: " << ESR_rc2str(rc) <<std::endl;
exit (-1);
}
}
Vocabulary::~Vocabulary()
{
SR_VocabularyDestroy(m_hVocab);
}
Pronunciation::Pronunciation()
{
}
Pronunciation::~Pronunciation()
{
}
void Pronunciation::clear()
{
m_Prons.clear();
for (unsigned int ii=0;ii<m_ModelIDs.size();ii++ )
{
m_ModelIDs[ii].clear();
}
m_ModelIDs.clear();
}
int Pronunciation::lookup( Vocabulary & vocab, std::string & phrase )
{
ESR_ReturnCode rc;
LCHAR prons[MAX_PRONS_LENGTH];
LCHAR* c_phrase;
size_t len;
LCHAR s[MAX_LINE_LENGTH];
strcpy (s, phrase.c_str() ); // No conversion for std::string to wchar
//clear();
memset (prons, 0x00, sizeof(LCHAR));
c_phrase = s;
SR_Vocabulary *p_SRVocab = vocab.getSRVocabularyHandle();
#if DEBUG
std::cout << "DEBUG: " << phrase <<" to be looked up" << std::endl;
#endif
rc = SR_VocabularyGetPronunciation( p_SRVocab, c_phrase, prons, &len );
if (rc != ESR_SUCCESS)
// std::cout <<"ERORORORORROOR!" <<std::endl;
std::cout <<"ERROR: " << ESR_rc2str(rc) << std::endl;
else {
#if DEBUG
std::cout <<"OUTPUT: " << prons << " num " << len << std::endl;
#endif
size_t len_used;
LCHAR *pron = 0;
for(len_used=0; len_used <len; ) {
pron = &prons[0]+len_used;
len_used += LSTRLEN(pron)+1;
#if DEBUG
std::cout << "DEBUG: used " << len_used << " now " << LSTRLEN(pron) << std::endl;
#endif
std::string pronString( pron ); // wstring conversion if needed
addPron( pronString );
#if DEBUG
std::cout << "DEBUG: " << phrase << " " << pron << std::endl;
#endif
}
}
return getPronCount();
}
int Pronunciation::addPron( std::string & s )
{
m_Prons.push_back( s );
return m_Prons.size();
}
int Pronunciation::getPronCount()
{ // returns number of prons
return m_Prons.size();
}
bool Pronunciation::getPron( int index, std::string &s )
{
// returns string length used
try {
s = m_Prons.at(index);
}
catch(std::out_of_range& err) {
std::cerr << "out_of_range: " << err.what() << std::endl;
}
return true;
}
void Pronunciation::print()
{
std::string s;
for (int ii=0; ii< getPronCount(); ii++) {
getPron(ii, s);
#if DEBUG
std::cout << "Pron #" << ii << ": " << s << std::endl;
#endif
}
}
void Pronunciation::printModelIDs()
{
std::string s;
for (int ii=0; ii< getPronCount(); ii++) {
getPron(ii, s);
#if DEBUG
std::cout << " Pron #" << ii << ": " << s << std::endl;
std::cout << " Model IDs: ";
#endif
for (int jj=0;jj<getModelCount(ii);jj++) {
std::cout << " " << getModelID(ii,jj);
}
#if DEBUG
std::cout << std::endl;
#endif
}
}
int Pronunciation::getPhonemeCount( int pronIndex )
{
std::string s;
getPron(pronIndex, s);
return s.size();
}
bool Pronunciation::getPhoneme( int pronIndex, int picIndex , std::string &phoneme )
{
std::string s;
getPron(pronIndex, s);
phoneme= s.at(picIndex);
return true;
}
bool Pronunciation::getPIC( int pronIndex, int picIndex, std::string &pic )
{
std::string pron;
char lphon;
char cphon;
char rphon;
getPron( pronIndex, pron );
int numPhonemes = pron.size();
if ( 1==numPhonemes ) {
lphon=GENERIC_CONTEXT;
rphon=GENERIC_CONTEXT;
cphon = pron.at(0);
}
else
{
if ( 0==picIndex ) {
lphon=GENERIC_CONTEXT;
rphon=GENERIC_CONTEXT;
}
else if( numPhonemes-1==picIndex ) {
lphon = pron.at(picIndex-1);
rphon=GENERIC_CONTEXT;
}
else {
lphon = pron.at(picIndex-1);
rphon = pron.at(picIndex+1);
}
cphon = pron.at(picIndex);
pic = lphon + cphon + rphon;
}
return true;
}
int Pronunciation::lookupModelIDs( AcousticModel &acoustic )
{
// Looks up all hmms for all prons
std::string pron;
char lphon;
char cphon;
char rphon;
int numProns = getPronCount();
int totalCount=0;
for (int ii=0;ii < numProns; ii++ )
{
getPron( ii, pron );
std::vector<int> idList; // Create storage
int numPhonemes = getPhonemeCount(ii);
if (1==numPhonemes) {
lphon=GENERIC_CONTEXT;
rphon=GENERIC_CONTEXT;
cphon = pron.at(0);
}
else
for ( int jj=0;jj<numPhonemes;jj++ )
{
std::string pic;
getPIC(ii, jj, pic);
lphon = pron.at(0);
cphon = pron.at(1);
rphon = pron.at(2);
int id = CA_ArbdataGetModelIdsForPIC( acoustic.getCAModelHandle(), lphon, cphon, rphon );
#if DEBUG
std::cout <<"DEBUG model id: " << lphon <<cphon << rphon << " "<< id << std::endl;
#endif
idList.push_back(id);
}
m_ModelIDs.push_back(idList);
totalCount+=numPhonemes;
}
return totalCount;
}
int Pronunciation::getModelCount( int pronIndex )
{
return m_ModelIDs[pronIndex].size();
}
int Pronunciation::getModelID( int pronIndex, int modelPos )
{
return m_ModelIDs[pronIndex][modelPos];
}
AcousticModel::AcousticModel( std::string & arbFileName )
{
m_CA_Arbdata = CA_LoadArbdata( arbFileName.c_str() );
if (!m_CA_Arbdata)
{
std::cout << "Error: while trying to load " << arbFileName.c_str() << std::endl;
exit (-1);
}
}
AcousticModel::~AcousticModel()
{
CA_FreeArbdata( m_CA_Arbdata);
}
int AcousticModel::getStateIndices(int id, std::vector<int> & stateIDs)
{
srec_arbdata *allotree = (srec_arbdata*) m_CA_Arbdata;
int numStates = allotree->hmm_infos[id].num_states;
#if DEBUG
std::cout << "getStateIndices: count = " << numStates <<std::endl;
#endif
for (int ii=0; ii <numStates; ii++ ) {
stateIDs.push_back( allotree->hmm_infos[id].state_indices[ii] );
#if DEBUG
std::cout << allotree->hmm_infos[id].state_indices[ii] ;
#endif
}
#if DEBUG
std::cout << std::endl;
#endif
return stateIDs.size();
}