⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugspeech.cpp

📁 .net 方面的开发说明资料。
💻 CPP
字号:
// ========================================================
// Speech plug (Microsoft Speech API 5.0)
//
// Design and Implementation by Floris van den Berg
// ========================================================

#include "Eplug.h"
#include "PlugSpeech.h"

// --------------------------------------------------------

void __stdcall
SAPICallback(WPARAM wparam, LPARAM lparam) {
	PlugSpeech *speech = (PlugSpeech *)wparam;

	EpEvent pm_event;
	pm_event.reference_id = 0;
	pm_event.protocol = CLSID_PROTOCOL_SYSTEM;
	pm_event.size = 0;
	pm_event.data = NULL;
	pm_event.timeout = 0;

    CSpEvent event;

    while (event.GetFrom(speech->m_recotxt) == S_OK) {
        switch (event.eEventId) {
			case SPEI_SOUND_START :    
				pm_event.msg = SYSTEM_SPEECH_START;

				EpDispatchEvent(speech->getGrid(), speech->getId(), &pm_event);
				break;

			case SPEI_SOUND_END :
				speech->m_recotxt->SetVoicePurgeEvent(SPFEI(SPEI_SOUND_START));

				pm_event.msg = SYSTEM_SPEECH_END;

				EpDispatchEvent(speech->getGrid(), speech->getId(), &pm_event);
				break;

            case SPEI_FALSE_RECOGNITION:
				pm_event.msg = SYSTEM_SPEECH_NOISE;
				pm_event.size = 0;
				pm_event.data = NULL;

				EpDispatchEvent(speech->getGrid(), speech->getId(), &pm_event);
				break;

            case SPEI_HYPOTHESIS :
            case SPEI_RECOGNITION :
				SPPHRASE *phrase;
				speech->m_recotxt->SetVoicePurgeEvent(SPFEI(SPEI_SOUND_START));

				ISpRecoResult *result = event.RecoResult();
				
				if (SUCCEEDED(result->GetPhrase(&phrase))) {
					CSpDynamicString dstrText;

					if (SUCCEEDED(result->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL))) {
						// get the alternates
						
						result->GetAlternates(phrase->Rule.ulFirstElement, phrase->Rule.ulCountOfElements, 32, speech->m_alt, &speech->m_alt_count);

						for (int i = 0, j = 0; i < speech->m_alt_count - 1; ++i) {
							CSpDynamicString altText;

							speech->m_alt[i + 1]->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &altText, NULL);

							char *tmp = altText.CopyToChar(); // who invented this brilliant interface?

							if (tmp) {
								speech->m_alt_string[j++] = tmp;
		
								CoTaskMemFree(tmp);
							}
						}

						// output the regognized phrase

						char *tmp = dstrText.CopyToChar(); // who invented this brilliant interface?

						pm_event.msg = SYSTEM_DATA_IN;
						pm_event.size = strlen(tmp) + 1;
						pm_event.data = (unsigned char *)tmp;
						pm_event.reference_id = j;

						EpDispatchEvent(speech->getGrid(), speech->getId(), &pm_event);

						pm_event.msg = SYSTEM_SPEECH_REGOGNITION;

						EpDispatchEvent(speech->getGrid(), speech->getId(), &pm_event);

						CoTaskMemFree(tmp);
					} else {
						pm_event.msg = SYSTEM_SPEECH_NOISE;
						pm_event.size = 0;
						pm_event.data = NULL;

						EpDispatchEvent(speech->getGrid(), speech->getId(), &pm_event);
					}
				}
				
                break;
        }
    }
}

// --------------------------------------------------------

PlugSpeech::PlugSpeech(Grid *grid, int id) :
inherited(grid, id) {
}

PlugSpeech::~PlugSpeech() {
}

// --------------------------------------------------------

bool
PlugSpeech::open(PlugProperties *info) {
    HRESULT hr = S_OK;

    CComPtr<ISpAudio> cpAudio;

    while (1) {
        // create a recognition engine

        hr = m_engine.CoCreateInstance(CLSID_SpSharedRecognizer);

        if (FAILED(hr))
            break;
       
        // create the command recognition context

        hr = m_engine->CreateRecoContext(&m_recotxt);

        if (FAILED(hr))
            break;

        // Let SR know that window we want it to send event information to, and using what message

        hr = m_recotxt->SetNotifyCallbackFunction(SAPICallback, (WPARAM)this, 0);

        if (FAILED(hr))
            break;

	    // Tell SR what types of events interest us.  Here we only care about command recognition.

		hr = m_recotxt->SetInterest(SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END), SPFEI(SPEI_RECOGNITION) | SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END));
        
        if (FAILED(hr))
            break;

		// do not retain audio

		hr = m_recotxt->SetAudioOptions(SPAO_NONE, NULL, NULL);

        if (FAILED(hr))
            break;

        // create a new grammar

        hr = m_recotxt->CreateGrammar(0, &m_grammar);
        
        if (FAILED(hr))
            break;

		// load the dictation file + set state

        hr = m_grammar->LoadDictation(NULL, SPLO_STATIC);
        
		if (FAILED(hr))
            break;

        hr = m_grammar->SetDictationState(SPRS_INACTIVE);

        if (FAILED(hr))
            break;

		return true;
    }

	close();
	return false;
}

void
PlugSpeech::close() {
	// release grammar, if loaded

    if (m_grammar)
        m_grammar.Release();

    // Release recognition context, if created

    if (m_recotxt) {
        m_recotxt->SetNotifySink(NULL);
        m_recotxt.Release();
    }

    // Release recognition engine instance, if created

	if (m_engine)
		m_engine.Release();
}

bool
PlugSpeech::connect(const char *host, int port) {
	m_grammar->SetDictationState(SPRS_ACTIVE);
	return true;
}

void
PlugSpeech::disconnect() {
	m_grammar->SetDictationState(SPRS_INACTIVE);
}

bool
PlugSpeech::supportsSending() {
	return false;
}

void
PlugSpeech::pollProgress() {
}

void *
PlugSpeech::getReferenceData(int id) {
	return (void *)m_alt_string[id].c_str();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -