在VC 中调用TTS动态链接库
用VC++(www.cppentry.com)创建一个视图基类为CFormView的MFC AppWizard(exe)工程:选择“File”,“New…”新建一MFC AppWizard(exe)工程TTSCall。最后一步选择基类为CformView。其余可取缺省设置。在Form上添加四个按钮,分别为:IDC_BUTTON1“朗读”;IDC_BUTTON2“暂停”;IDC_BUTTON4“恢复”;IDC_BUTTON3“停止”,以及一编辑框IDC_EDIT1。并添加四个按钮的处理函数:OnRead、OnPause、OnResume、OnStop和编辑框EN_CHANGE事件的响应函数:OnChangeEdit。通过ClassWizard为编辑框同一变量m_Text绑定。最后为CTTSCallView类添加两个变量:BOOL m_bCreated; HINSTANCE m_DLL;并在构造函数中初始化之。
CTTSCallView::CTTSCallView(): CFormView(CTTSCallView::IDD) { //{{AFX_DATA_INIT(CTTSCallView) m_Text = _T("Hello! Welcome to use this software developed by LangRui."); //}}AFX_DATA_INIT m_DLL = NULL; m_bCreated=FALSE; } |
在视类中的初始化函数中添加代码:
void CTTSCallView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON4)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE); } |
在实现与语音朗读相关的各种功能时,首先调用LoadLibrary()函数动态加载前面用Delphi制作的动态连接库,然后通过GetProcAddress()函数取得此DLL模块中的各相关导出函数并通过该函数执行相应的语音朗读操作。在执行完毕后,需要通过AfxFreeLibrary()函数卸载先前加载的动态链接库。下面是这部分的实现代码:
实现朗读功能:
void CTTSCallView::OnRead() { m_DLL=LoadLibrary("Project1.dll"); //动态加载动态连接库 void (*Create)(void); //取得DLL中的Create函数 Create=(void(*)(void))::GetProcAddress(m_DLL,"Create"); Create(); m_bCreated=TRUE; void (*Read)(char*); //取得DLL 中的Read函数 Read=(void(*)(char*))::GetProcAddress(m_DLL,"Read"); //获取编辑框内容 UpdateData(TRUE); char buf[10000]; ::strcpy(buf,m_Text); Read(buf);//朗读编辑框的内容。 GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);//“朗读”按钮不可用 GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); //“暂停”按钮可用 GetDlgItem(IDC_BUTTON4)->EnableWindow(FALSE);//“恢复”按钮不可用 GetDlgItem(IDC_BUTTON3)->EnableWindow(TRUE); //“停止”按钮可用 } |
实现暂停功能:
void CTTSCallView::OnPause() { m_DLL=LoadLibrary("Project1.dll"); void (*Pause)(); Pause=(void(*)())::GetProcAddress(m_DLL,"Pause"); BOOL (*IsSpeaking)(); //判断是否正在朗读 IsSpeaking=(BOOL(*)())::GetProcAddress(m_DLL,"IsSpeaking"); if(IsSpeaking()) { Pause(); GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON4)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON3)->EnableWindow(TRUE); } } |
实现恢复功能:
void CTTSCallView::OnResume() { m_DLL=LoadLibrary("Project1.dll"); void (*Resume)(); Resume=(void(*)())::GetProcAddress(m_DLL,"Resume"); BOOL (*IsSpeaking)(); IsSpeaking=(BOOL(*)())::GetProcAddress(m_DLL,"IsSpeaking"); if(!IsSpeaking()) { Resume(); GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON4)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON3)->EnableWindow(TRUE); } } |
实现停止功能:
void CTTSCallView::OnStop() { m_DLL=LoadLibrary("Project1.dll"); void (*Stop)(); Stop=(void(*)())::GetProcAddress(m_DLL,"Stop"); Stop();//停止朗读 GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON4)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE); } |
当编辑框内容发生改变,而又没有进行朗读时,应当处于准备朗读状态:
void CTTSCallView::OnChangeEdit() { if(m_bCreated) { m_DLL=LoadLibrary("Project1.dll"); BOOL (*IsSpeaking)(); IsSpeaking=(BOOL(*)())::GetProcAddress(m_DLL,"IsSpeaking"); if(!IsSpeaking()) { GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON4)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON3)->EnableWindow(FALSE); } } } |
当程序退出时应释放加载的动态链接库,添加虚函数DestoryWindow()
BOOL CTTSCallView::DestroyWindow() { AfxFreeLibrary(m_DLL); return CFormView::DestroyWindow(); } |
运行测试
将由Delphi编制的动态链接库Project1.dll复制到VC的TTSCall 工程的Debug 目录下。编译并运行TTSCall工程,在编辑框上写一端英文,按下“朗读”按钮,就可以听到利用TTS全程化语音技术所发出的抑扬顿挫的声音。
小结
TTS是全程化语音技术,它可以实现英文单词以及短语的准确发音,甚至可以独立完成整篇英文文章的流畅朗读。而且TTS技术是建立在英文阅读规则基础上的语音合成技术,并非将单词一个一个拆开机械得进行朗读,因此在语气的转折和单词的衔接上都非常自然,问句和祈使句的升降调也能很好的表现出来。
|