S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

转 VC使用TTS发声

Posted on 2010-05-18 23:32 S.l.e!ep.¢% 阅读(1924) 评论(0)  编辑 收藏 引用 所属分类: VC
转 VC使用TTS发声
2010-01-08 17:13
MFC使用TTS发音,后来在VC知识库发现一篇不错的文章,大家可以上去看一下(http://www.vckbase.com/document/viewdoc/?id=1051)但是文章写得太简单,而且他实现的方法一定要在创建MFC项目的时候在选上Automation,而我现在讲一下在我们以有的项目上添加TTS发音功能(创建项目的时候没有选上Automation)。
      下面我把实现步骤写下来:
1、        下载Microsoft Speech SDK, version 5.1,要实现中文发音的话要再下载个SimpChinese Speech Package
2、        安装了Microsoft Speech SDK, version 5.1后在C:\Program Files\Common Files\Microsoft Shared\Speech目录下找到sapi.dll
3、        sapi.dll复制到你的项目文件下。
4、        打开 MFC ClassWizard,选择 Automation 页,单击按钮"Add Class…",选择"From a type library…",选中"sapi.dll"文件,这时系统会出现 confirm Classes 对话框,询问将要导入的类(有20多个类)。如果只要实现发音功能,只要导入IspeechObjectTokenIspeechObjectTokensIspeechVoice3个,其它类的功能我还在研究中。(如果在建项目的时候勾选了Automation,系统会自动帮你生成3个文件,分别是DlgProxy.cppDlgProxy.h还有一个根据你项目名.odl文件,如果没有勾选上Automation就不会创建这三个文件,所以我们要实现发音功能,就要自己添加修改这三个文件)
5、        没有自动生成的文件怎么办呢?最好的办法就是新建一个项目,它的名称和你现有的项目名称一样,然后在创建MFC Dialog Based项目的时候,选上Automation,然后做步骤4,将它生成的3个文件复制并加入到你现有项目中。
6、        复制好后,就要在一些文件上添加修改代码了。下面我以一个名为test的工程为例子首先在test.cpp文件添加这些代码(红色):
     BOOL CTestApp::InitInstance()
{
      if (!AfxOleInit())
      {
            AfxMessageBox("OLE 程序初始化失败。请确认 OLE 库程序是正确的版本");
           return FALSE;
      }
      AfxEnableControlContainer();
      // Standard initialization
      // If you are not using these features and wish to reduce the size
      // of your final executable, you should remove from the following
      // the specific initialization routines you do not need.
#ifdef _AFXDLL
      Enable3dControls();                 // Call this when using MFC in a shared DLL
#else
      Enable3dControlsStatic();   // Call this when linking to MFC statically
#endif
           if (RunEmbedded() || RunAutomated())
      {
           // Register all OLE server (factories) as running. This enables the
           // OLE libraries to create objects from other applications.
           COleTemplateServer::RegisterAll();
      }
      else
      {
           // When a server application is launched stand-alone, it is a good idea
           // to update the system registry in case it has been damaged.
           COleObjectFactory::UpdateRegistryAll();
      }
      CTestDlg dlg;
      m_pMainWnd = &dlg;
      int nResponse = dlg.DoModal();
      if (nResponse == IDOK)
      {
           // TODO: Place code here to handle when the dialog is
           // dismissed with OK
      }
7、        接着在testDlg.h文件添加以下代码:
     #include "sapi.h"
class CtestDlgAutoProxy;
/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog
class CTestDlg : public CDialog
{
      DECLARE_DYNAMIC(CTestDlg);
      friend class CtestDlgAutoProxy;
// Construction
public:
      virtual ~CTestDlg();
      CTestDlg(CWnd* pParent = NULL); // standard constructor
     ISpeechObjectToken recoObject;
      LPDISPATCH pDisp;
      CLSID CLSID_SpVoice;
      ISpeechVoice voice;
      ISpeechObjectTokens voiceList;
// Dialog Data
      //{{AFX_DATA(CTestDlg)
      enum { IDD = IDD_TEST_DIALOG };
     CComboBox   m_voice; //拖控件并添加control类型数据成员
      long    m_Rate;
      long    m_Vol;
      //}}AFX_DATA
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CTestDlg)
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);   // DDX/DDV support
      //}}AFX_VIRTUAL
// Implementation
protected:
      HICON m_hIcon;
     CtestDlgAutoProxy* m_pAutoProxy;
      // Generated message map functions
      //{{AFX_MSG(CTestDlg)
     
8、        接着在testDlg.cpp添加下面代码:
#include "DlgProxy.h"
////////////////////////////////////
IMPLEMENT_DYNAMIC(CTestDlg, CDialog);
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CTestDlg)
       // NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pAutoProxy = NULL;
}
CTestDlg::~CTestDlg()
{
 if (m_pAutoProxy != NULL)
       m_pAutoProxy->m_pDialog = NULL;
}
//////////////////////////
BOOL CTestDlg::OnInitDialog()
{
       。。。。。。。。。。。。。
       // TODO: Add extra initialization here
CLSIDFromProgID(L"SAPI.SpVoice", &CLSID_SpVoice);
voice.CreateDispatch(CLSID_SpVoice);
pDisp = voice.m_lpDispatch;
HRESULT hr = pDisp->QueryInterface(CLSID_SpVoice, (void**)&voice.m_lpDispatch);
if (hr == S_OK) {
       pDisp->Release();
}
else {
       voice.AttachDispatch(pDisp, TRUE);
}
m_Rate=0;//语速
voice.SetRate(m_Rate);
m_Vol=100; //音量
voice.SetVolume(m_Vol);
//用来获取支持多少种声音
voiceList=voice.GetVoices(NULL,NULL);
       m_voice.SetCurSel(0);
voice.SetRefVoice(voiceList.Item(0)); //item(0)是英文发音,果装了中文包可设item(3)
//为中文发音
return TRUE; // return TRUE unless you set the focus to a control
}
9、        添加个button
void CTestDlg::OnButton1()
{
                 voice.Speak("you", 1);//发音
}
10、     DlgProxy.cpp找到下面一句代码:
IMPLEMENT_OLECREATE2(CtestDlgAutoProxy, "test.Application", 0xc1b93196, 0x3df8, 0x4a61, 0xb1, 0x22, 0xa4, 0xc2, 0x8e, 0xe2, 0x75, 0xdb) 并将它注释掉。(我不知道原因,但不注释的话运行会出错,如果有朋友知道原因的话请告诉我)

经过上面的步骤后,就可以实现到发音了,可以用IspeechVoice类的函数调发音的速度和音量等。我试过了,在默认情况下发音和金山词霸差不多。


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理