// Transcribe.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0502		// Specifies that the minimum required platform is XP SP2.   
#endif

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <fstream>
#include <sphelper.h>

int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT hr = E_FAIL;

	USES_CONVERSION;

	if (argc != 3) {
		std::cout << "Error! Must provide the path to a WAV file" << std::endl
			<< "and the path for an output txt file" << std::endl
			<< "as the first and second command-line arguments." << std::endl;
		return 1;
	}

	// Initialize COM
	if (SUCCEEDED(hr = ::CoInitialize(NULL)))
    {
        {
			CComPtr<ISpRecognizer> cpEngine;
            CComPtr<ISpRecoContext> cpRecoCtxt;
            CComPtr<ISpRecoGrammar> cpGrammar;
            CComPtr<ISpRecoResult> cpResult;
			CComPtr<ISpStream> cpStream;

			hr = cpStream.CoCreateInstance(CLSID_SpStream);
			hr = cpStream->BindToFile(argv[1], SPFM_OPEN_READONLY, NULL, NULL,
										SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_END_SR_STREAM));

			// Create in-proc recognizer...
			hr = cpEngine.CoCreateInstance(CLSID_SpInprocRecognizer);
            hr = cpEngine->CreateRecoContext(&cpRecoCtxt);
			// ... and hook it up to our WAV file
			hr = cpEngine->SetInput(cpStream, TRUE);

			hr = cpRecoCtxt->SetNotifyWin32Event();
			// Ignore non-recognition events, except end-of-stream
			hr = cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_END_SR_STREAM),
				                         SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_END_SR_STREAM));
			hr = cpRecoCtxt->CreateGrammar(0, &cpGrammar);
			// Enable general dictation mode
			hr = cpGrammar->LoadDictation(NULL, SPLO_STATIC);

			CSpEvent spEvent;
			CSpDynamicString dstrText;

			std::ofstream ofile(argv[2], std::ios::trunc);

			std::cout << "Starting speech recognition..." << std::endl;
			hr = cpGrammar->SetDictationState(SPRS_ACTIVE);
			while(S_OK == cpRecoCtxt->WaitForNotifyEvent(INFINITE)) {
				while(S_OK == spEvent.GetFrom(cpRecoCtxt)) {
					switch(spEvent.eEventId) {
						case SPEI_RECOGNITION:
							if (SUCCEEDED(spEvent.RecoResult()->GetText(SP_GETWHOLEPHRASE,
																		SP_GETWHOLEPHRASE,
																		TRUE, &dstrText, NULL))) {
								ofile << W2A(dstrText) << "\n";	
							}
							break;

						case SPEI_END_SR_STREAM:
							goto recognition_done;
					}
				}
			}
recognition_done:
			std::cout << "Cleaning up..." << std::endl;
			ofile.close();
			hr = cpGrammar->SetDictationState(SPRS_INACTIVE);
			hr = cpGrammar->UnloadDictation();
			hr = cpStream->Close();
			
		}
	}

	// Clean up COM
	::CoUninitialize();
	return 0;
}


