转:VC使用TTS发声

这几天在搞TTS发音,发现网上有关这方面的资料不多,特别是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 多个类)。如果只要实现发音功能,只要导入 IspeechObjectToken IspeechObjectTokens IspeechVoice 3 个,其它类的功能我还在研究中。(如果在建项目的时候勾选了 Automation ,系统会自动帮你生成 3 个文件,分别是 DlgProxy.cpp DlgProxy.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 类的函数调发音的速度和音量等。我试过了,在默认情况下发音和金山词霸差不多。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值