Path: blob/master/examples/cppwin/TensorflowTTSCppInference/phonemizer.cpp
1559 views
#include "phonemizer.h"1#include <fstream>2#include "ext/ZCharScanner.h"34int32_t GetID(const std::vector<IdStr>& In, const std::string &InStr)5{6for (const IdStr& It : In)7if (It.STR == InStr)8return It.ID;910return -1;11}1213std::string GetSTR(const std::vector<IdStr>& In, int32_t InID)14{15for (const IdStr& It : In)16if (It.ID == InID)17return It.STR;1819return "";2021}2223std::vector<IdStr> Phonemizer::GetDelimitedFile(const std::string &InFname)24{252627std::ifstream InFile (InFname);2829int32_t CuID;30std::string Tok;31std::vector<IdStr> RetVec;323334std::string Line;35while (std::getline(InFile, Line)) {3637if (Line.find("\t") == std::string::npos)38continue;394041ZStringDelimiter Deline(Line);42Deline.AddDelimiter("\t");4344CuID = stoi(Deline[1]);45Tok = Deline[0];464748RetVec.push_back(IdStr{CuID,Tok});4950}5152return RetVec;535455}5657void Phonemizer::LoadDictionary(const std::string &InDictFn)58{59606162std::ifstream InFile (InDictFn);6364std::string Word;65std::string Phn;666768if (Dictionary.size())69Dictionary.clear();7071727374std::string Line;75while (std::getline(InFile, Line)) {7677if (Line.find("\t") == std::string::npos)78continue;798081ZStringDelimiter Deline(Line);82Deline.AddDelimiter("\t");8384Word = Deline[0];85Phn = Deline[1];868788Dictionary.push_back(StrStr{Word,Phn});8990}91// Sort so lookup can be a bit optimized92std::sort(Dictionary.begin(),Dictionary.end());939495}9697std::string Phonemizer::DictLookup(const std::string &InWord)98{99100for (size_t w = 0 ; w < Dictionary.size();w++)101{102const StrStr& Entr = Dictionary[w];103104if (Entr.Word.size() != InWord.size())105continue;106107if (Entr.Word == InWord)108return Entr.Phn;109110}111112return "";113114}115116117118119Phonemizer::Phonemizer()120{121122}123124bool Phonemizer::Initialize(const std::string InPath)125{126// Load indices127try {128CharId = GetDelimitedFile(InPath + "/char2id.txt");129PhnId = GetDelimitedFile(InPath + "/phn2id.txt");130131// Load model132G2pModel.Initialize(InPath + "/model");133134LoadDictionary(InPath + "/dict.txt");135}136catch (...){137return false;138}139140141142143return true;144145146}147148std::string Phonemizer::ProcessWord(const std::string &InWord,float Temperature)149{150// First we try dictionary lookup151// This is because the g2p model can be unreliable, we only want to use it for novel sentences152153std::string PhnDict = DictLookup(InWord);154if (!PhnDict.empty())155return PhnDict;156157std::vector<int32_t> InIndexes;158InIndexes.reserve(InWord.size());159160// Turn word into indices161for (const char ch : InWord)162{163std::string Single(1,ch);164int32_t Idx = GetID(CharId,Single);165166if (Idx != -1)167InIndexes.push_back(Idx);168169170}171172TFTensor<int32_t> PhnPrediction = G2pModel.DoInference(InIndexes,Temperature);173174175std::string RetStr = "";176bool FirstIter = true;177178for (int32_t PhnIdx : PhnPrediction.Data)179{180std::string PhnTxt = GetSTR(PhnId,PhnIdx);181if (!PhnTxt.empty())182{183if (!FirstIter)184RetStr.append(" ");185186RetStr.append(PhnTxt);187188}189190FirstIter = false;191}192193194195return RetStr;196197}198199std::string Phonemizer::GetPhnLanguage() const200{201return PhnLanguage;202}203204void Phonemizer::SetPhnLanguage(const std::string &value)205{206207PhnLanguage = value;208}209210std::string Phonemizer::GetGraphemeChars()211{212213std::string RetAllowed = "";214for (const IdStr& Idx : CharId)215RetAllowed.append(Idx.STR);216217return RetAllowed;218219}220221222223224bool operator<(const StrStr &right, const StrStr &left)225{226return right.Word.length() < left.Word.length();227}228229230