#include "SimpleRecognizer.h"
#include <sstream>
//=============================================================================
// Callback for messages from the speech port
void logger(const char* msg, void* userdata)
{
std::cout << msg << std::endl;
}
//=============================================================================
// Code to plug LVSemanticData into any standard stream
std::ostream& operator << (std::ostream& os, const LVSemanticData& Data)
{
int i;
LVSemanticObject Obj;
switch (Data.Type())
{
case SI_TYPE_BOOL:
os << Data.GetBool() << "\n";
break;
case SI_TYPE_INT:
os << Data.GetInt() << "\n";
break;
case SI_TYPE_DOUBLE:
os << Data.GetDouble() << "\n";
break;
case SI_TYPE_STRING:
os << Data.GetString() << "\n";
break;
case SI_TYPE_OBJECT:
Obj = Data.GetSemanticObject();
for (i = 0; i < Obj.NumberOfProperties(); ++i)
{
os << "<property name=" << Obj.PropertyName(i) << ">\n";
os << Obj.PropertyValue(i);
os << "</property>\n";
}
break;
case SI_TYPE_ARRAY:
for (i = 0; i < Data.GetSemanticArray().Size(); ++i)
{
os << "<element>\n";
os << Data.GetArray().At(i);
os << "</element>\n";
}
break;
}
return os;
}
//=============================================================================
// Code to plug LVInterpretation into any standard stream
std::ostream& operator << (std::ostream& os, const LVInterpretation& Interp)
{
os << "<interpretation grammar=\"" << Interp.GrammarLabel()
<< "\" score=\"" << Interp.Score() << "\">" << std::endl;
os << "<result name=\"" << Interp.ResultName() << "\">" << std::endl;
os << Interp.ResultData();
os << "</result>" << std::endl;
os << "<input>" << std::endl;
os << Interp.InputSentence() << std::endl;
os << "</input>" << std::endl;
os << "</interpretation>";
return os;
}
//=============================================================================
void SimpleRecognizer::WaitUntilDone()
{
while (!finished_decode) Sleep(50);
}
//=============================================================================
SimpleRecognizer::SimpleRecognizer() :
voiceChannel(1),
finished_decode(true),
AudioThread(NULL)
{
LVSpeechPort::RegisterAppLogMsg(logger,NULL,6);
int v = port.CreateClient(logger,NULL,6);
if (v != LV_SUCCESS)
{
std::cout << LVSpeechPort::ReturnErrorString(port.GetOpenPortStatus())
<< std::endl;
exit(-1);
}
// Turn on frequency based voice activity detector
port.StreamSetParameter(STREAM_PARM_DETECT_BARGE_IN, 1);
port.StreamSetParameter(STREAM_PARM_DETECT_END_OF_SPEECH, 1);
port.StreamSetParameter(STREAM_PARM_VOICE_CHANNEL, voiceChannel);
port.StreamSetParameter(STREAM_PARM_GRAMMAR_SET, LV_ACTIVE_GRAMMAR_SET);
//Let the port handle the decode process
port.StreamSetParameter(STREAM_PARM_AUTO_DECODE, 1);
//and use semantic interpretation processor
port.StreamSetParameter(STREAM_PARM_DECODE_FLAGS, LV_DECODE_SEMANTIC_INTERPRETATION);
port.StreamSetStateChangeCallBack(PortCB, this);
}
//=============================================================================
SimpleRecognizer::~SimpleRecognizer()
{
port.DestroyClient();
}
//=============================================================================
void SimpleRecognizer::PortCB(int NewState, unsigned int TotalBytes,
unsigned int RecordedBytes, void* UserData)
{
SimpleRecognizer* self = (SimpleRecognizer*)UserData;
switch (NewState)
{
case STREAM_STATUS_END_SPEECH:
if (!self->finished_decode)
{
self->AudioThread->StopStream();
self->GetAnswers();
self->finished_decode = true;
}
break;
case STREAM_STATUS_STOPPED:
if (!self->finished_decode)
{
self->AudioThread->StopStream();
self->GetAnswers();
self->finished_decode = true;
}
break;
case STREAM_STATUS_NOT_READY:
break;
case STREAM_STATUS_READY:
self->finished_decode = false;
self->AudioThread->StartStream(AudioCB,self);
break;
}
}
//=============================================================================
void SimpleRecognizer::LoadGrammar(const std::string& grammar_name,
const std::string& grammar_location)
{
port.LoadGrammar(grammar_name.c_str(), grammar_location.c_str());
}
//=============================================================================
bool SimpleRecognizer::AudioCB(char* audio_data, int audio_data_size,
void* user_data)
{
SimpleRecognizer* self = (SimpleRecognizer*)user_data;
self->port.StreamSendData(audio_data, audio_data_size);
return true;
}
//=============================================================================
void SimpleRecognizer::Recognize(AudioStreamer* Audio, const std::string& grammar_name)
{
finished_decode = false;
AudioThread = Audio;
// Clear out old grammars.
port.DeactivateGrammars();
port.ActivateGrammar(grammar_name.c_str());
port.AddEvent(EVENT_START_DECODE_SEQ);
port.StreamSetParameter(STREAM_PARM_SOUND_FORMAT, ULAW_8KHZ);
port.StreamStart();
}
//=============================================================================
void SimpleRecognizer::GetAnswers()
{
int val;
val = port.WaitForEngineToIdle(3000,voiceChannel);
if (val < 0)
{
result = "<noanswer/>";
return;
}
//View the results of the decode:
std::stringstream ss;
int numInterp = port.GetNumberOfInterpretations(voiceChannel);
for (int t = 0; t < numInterp; ++t)
{
ss << port.GetInterpretation(voiceChannel, t);
}
result = ss.str();
}
//=============================================================================
const std::string& SimpleRecognizer::GetResult() {return result;}
//=============================================================================