最近研究了下调用微软TTS引擎进行朗读的相关资料,发现其实很简单,特发文与众位博友共享。

首先看看微软MSDN官方文档是如何调用TTS的

#include <stdafx.h>
#include <sapi.h>

int main(int argc, char* argv[])
{
    ISpVoice * pVoice = NULL;

    if (FAILED(::CoInitialize(NULL)))
        return FALSE;

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice;);
    if( SUCCEEDED( hr ) )
    {
        hr = pVoice->Speak(L"Hello world", 0, NULL);
        pVoice->Release();
        pVoice = NULL;
    }

    ::CoUninitialize();
    return TRUE;
}

可以发现其实很简单,就是初始化COM后,创建ISpVoice的实例调用Speak方法即可,如果想更加深入的了解这方面的知识,可以查阅MSDN,http://msdn.microsoft.com/en-us/library/ee125082(v=VS.85).aspx

 

Qt上使用COM非常简单,ActivityQt是Qt上用了和COM打交道,由于是调用COM,我们使用QAxObject即可满足要求。

首先设计一个接口

#include <QObject>

class ITTS : public QObject
{
	Q_OBJECT
public:
	ITTS(void);
	virtual ~ITTS(void);

	virtual bool initSpeech() = 0;
	virtual bool speak(QString & txt) = 0;
	virtual void pause() = 0;
	virtual void resume() = 0;
	virtual void stop() = 0;

	//rate range : -10 - 10
	virtual int rate() = 0; 
	virtual void setRate(int rate) = 0;

	//volume range : 0 - 100
	virtual int volume() = 0;
	virtual void setVolume(int value)  = 0;
	virtual bool isSpeaking() = 0;

signals:

	void speakComplete();

};

虽然我们是再Win7上使用,由于以后可能还有开发XP上的、Linux上的TTS,所以我们定义一个接口,在我们的调用类中只需要定义一个接口的指针就可以,然后根据实际的环境在初始化中初始化不同环境上的TTS实例,这个我们以后再来演示

根据Win7上的TTS,我们来创建Win7TTS类,继承于我们上面定义的ITTS

class Win7TTS :
	public ITTS
{
	Q_OBJECT 
public:
	Win7TTS(void);
	virtual ~Win7TTS(void);

	virtual bool initSpeech();
	virtual bool speak(QString & txt);
	virtual void pause();
	virtual void resume();
	virtual void stop();

	//rate range : -10 - 10
	virtual int rate(); 
	virtual void setRate(int rate);

	//volume range : 0 - 100
	virtual int volume();
	virtual void setVolume(int value) ;
	virtual bool isSpeaking();
private slots:

	void dealevent(QString name, int arc , void* argv);

private:
	QAxObject _voice;
	bool _binit;
	bool _bReading;
};

_voice 就是我们用来创建ISpVoice Com对象的成员

 

 

void) :
_binit(0),
_bReading(0)
{
}

Win7TTS::~Win7TTS(void)
{
}


bool Win7TTS::initSpeech()
{

	if(_binit)
		return true;

	_binit = this->_voice.setControl("96749377-3391-11D2-9EE3-00C04F797396");
	
	if(_binit)
	{
		connect(&this->_voice,SIGNAL(signal(QString, int, void*)), this, SLOT(dealevent(QString, int, void*)));
	}

	return _binit;
}

bool Win7TTS::speak(QString & txt)
{
	if(!_binit)
		return false;

	int result = this->_voice.dynamicCall("Speak(QString, SpeechVoiceSpeakFlags)", txt ,1).toInt();
	_bReading = true;
	return result;
}

void Win7TTS::pause()
{
	if(!_binit)
		return;
	_bReading = false;
	this->_voice.dynamicCall("Pause()");
}

void Win7TTS::resume()
{
	if(!_binit)
		return;
	_bReading = true;
	this->_voice.dynamicCall("Resume()");
}

void Win7TTS::stop()
{
	if(!_binit)
		return;
	_bReading = false;
	int result = this->_voice.dynamicCall("Speak(QString, SpeechVoiceSpeakFlags)", "" ,2).toInt();
}

bool Win7TTS::isSpeaking()
{
	return _bReading;
}

//rate range : -10 - 10
int Win7TTS::rate()
{
	if(!_binit)
		return -99999;

	return this->_voice.property("Rate").toInt();
} 

void Win7TTS::setRate(int rate)
{
	if(!_binit)
		return;

	this->_voice.dynamicCall("SetRate(int)", rate);
}

//volume range : 0 - 100
int Win7TTS::volume()
{

	if(!_binit)
		return -99999;

	return this->_voice.property("Volume").toInt();
}

void Win7TTS::setVolume(int value) 
{
	if(!_binit)
		return;

	this->_voice.dynamicCall("SetVolume(int)", value);
}

void Win7TTS::dealevent(QString name, int arc , void* argv)
{
	if(name == "EndStream(int,QVariant)")
	{
		_bReading = false;
		emit speakComplete();
	}
}

TTS的框架已经搭好了,现在让我们试试TTS的魅力吧,稍后上传一个TTS的SAMPLE,可以下载下来玩玩!

 

WIN7下使用Qt调用微软TTS进行文本朗读

 

Win7 TTS 示例 

相关文章:

  • 2021-08-03
  • 2022-12-23
  • 2021-09-19
猜你喜欢
  • 2021-10-17
  • 2021-09-24
  • 2021-12-25
  • 2021-05-13
  • 2021-09-28
  • 2021-07-25
相关资源
相似解决方案