bool FSpeechRecognitionWorker::Init() {

	std::string modelPath = contentPath_str + "model/" + langStr + "/" + langStr;
	std::string languageModel = contentPath_str + "model/" + langStr + "/" + langStr + ".lm.bin";
	std::string dictionaryPath = contentPath_str + "model/" + langStr + "/" + langStr + ".dict";

	// load dictionary
	dictionaryMap.clear();

	std::ifstream file(dictionaryPath);
	std::vector<std::string> words;
	std::string currentLine;

	while (file.good())
	{
		std::getline(file, currentLine);
		std::string word = currentLine.substr(0, currentLine.find(" "));
		std::string phrase = currentLine.substr(currentLine.find(" ") + 1, currentLine.size());
		dictionaryMap.insert(make_pair(word, phrase));
	}

	// Start Sphinx
	config = cmd_ln_init(NULL, ps_args(), 1,
		"-hmm", modelPath.c_str(),
		"-lm", languageModel.c_str(),
		NULL);
	
	ps = ps_init(config);

	if (!Manager | !ps) {
		ClientMessage(FString(TEXT("Speech Recognition Thread failed to start")));
		initSuccess = false;
		return false;
	}

	// only include the words/phrases that have been added
	for (auto It = dictionaryList.CreateConstIterator(); It; ++It)
	{
		FString word = *It;
		std::string wordStr = std::string(TCHAR_TO_UTF8(*word));
		if (dictionaryMap.find(wordStr) != dictionaryMap.end())
		{
			std::string phraseStr = dictionaryMap.at(wordStr);
			ps_add_word(ps, wordStr.c_str(), phraseStr.c_str(), TRUE);
		}
	}

	// attempt to open the default recording device
	if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),
		(int)cmd_ln_float32_r(config,
		"-samprate"))) == NULL) {
			ClientMessage(FString(TEXT("Failed to open audio device")));
			initSuccess = false;
			return initSuccess;
	}

	utt_started = 0;
	return true;
}
 ReturnType Recognizer::addWords(const std::vector<Word>& words) {
   if (decoder == NULL) return BAD_STATE;
   for (int i=0 ; i<words.size() ; ++i) {
     // This case is not properly handeled by ps_add_word, so we treat it separately
     if (words.at(i).pronunciation.size() == 0) return RUNTIME_ERROR;
     if (ps_add_word(decoder, words.at(i).word.c_str(), words.at(i).pronunciation.c_str(), 1) < 0) return RUNTIME_ERROR;
   }
   return SUCCESS;
 }
 ReturnType Recognizer::addWords(const std::vector<Word>& words) {
   if (decoder == NULL) return BAD_STATE;
   for (int i=0 ; i<words.size() ; ++i)
     if (ps_add_word(decoder, words.at(i).word.c_str(), words.at(i).pronunciation.c_str(), 1) < 0) return RUNTIME_ERROR;
   return SUCCESS;
 }