Qt中的Windows Speech API。在main()中工作,但在课堂上有很多错误

时间:2013-11-27 01:15:29

标签: c++ qt sapi

所以我首先尝试做一个简短的例子,让主要功能中的文本到语音转换。这工作没有问题。代码如下所示:

main.cpp中:

#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QDebug>
#include <sapi.h>
#include <windows.h>
#include <atlbase.h>
#include "sphelper.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/GC/main.qml"));
    viewer.showExpanded();

    CComPtr<ISpObjectToken>         cpVoiceToken;
    CComPtr<IEnumSpObjectTokens>    cpEnum;
    ISpVoice *                      pVoice = NULL;
    ULONG                           count = 0;

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

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

    if(SUCCEEDED(hr))
    {
        //Enumerate voices.
        hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum);
    }
    else
    {
         qDebug() << "Failed to initialize SAPI5";
    }

    if(SUCCEEDED(hr))
    {
        //Get number of voices.
        hr = cpEnum->GetCount(&count);
        qDebug() << "TTS voices found: " + QString::number(count);
    }
    else
    {
        qDebug() << "Failed to enumerate voices. Using default.";
        hr = S_OK;
    }

    if(SUCCEEDED(hr))
    {
        cpVoiceToken.Release();

        cpEnum->Item(4, &cpVoiceToken);

        pVoice->SetVoice(cpVoiceToken);
        hr = pVoice->Speak(L"Hello! How are you?", 0, NULL);
        pVoice->Release();
        pVoice = NULL;
    }

    ::CoUninitialize();



    qDebug() << "End";

    return app.exec();
}

这会输出我在电脑上安装的声音数量并说出文字:“你好!你好吗?”。

当我现在将此代码移到类中时:

tts.h:

#ifndef TTS_H
#define TTS_H

#include <sapi.h>
#include <windows.h>
#include <atlbase.h>
#include "sphelper.h"

class Tts
{
public:
    Tts();
    bool Initialize();
    HRESULT Speak(char * text, ISpVoice * pVoice);

private:

};

#endif // TTS_H

tts.cpp:

#include "tts.h"
#include <QDebug>
#include <sapi.h>
#include <windows.h>
#include <atlbase.h>
#include "sphelper.h"


Tts::Tts()
{
}

bool Tts::Initialize()
{    
    CComPtr<ISpObjectToken>         cpVoiceToken;
    CComPtr<IEnumSpObjectTokens>    cpEnum;
    ISpVoice *                      pVoice = NULL;
    ULONG                           count = 0;

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

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

    if(SUCCEEDED(hr))
    {
        //Enumerate voices.
        hr = SpEnumTokens(SPCAT_VOICES, NULL, NULL, &cpEnum);
    }
    else
    {
        qDebug() << "Failed to initialize SAPI5";
    }

    if(SUCCEEDED(hr))
    {
        //Get number of voices.
        hr = cpEnum->GetCount(&count);
        qDebug() << "TTS voices found: " + QString::number(count);
    }
    else
    {
        qDebug() << "Failed to enumerate voices. Using default.";
        hr = S_OK;
    }

    if(SUCCEEDED(hr))
    {
        cpVoiceToken.Release();

        cpEnum->Item(4, &cpVoiceToken);

        pVoice->SetVoice(cpVoiceToken);
        Speak("Some text here", pVoice);
        pVoice->Release();
        pVoice = NULL;
    }

    ::CoUninitialize();

    return true;
}

HRESULT Tts::Speak(char * text, ISpVoice * pVoice)
{
    HRESULT hr;

    hr = pVoice->Speak(L"Hello! How are you?", 0, NULL);

    return hr;
}

main.cpp:

#include <QtCore>
#include <QtGui/QGuiApplication>
#include <QtQuick>
#include "qtquick2applicationviewer.h"
#include <QDebug>
#include "tts.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/GC/main.qml"));

    viewer.showExpanded();
    viewer.showMaximized();

    return app.exec();
}

我刚刚包含了tts.h头文件并且遇到了很多错误。我尝试过重建,清理和删除build文件夹中的文件,但没有运气。在没有包含在主程序中的tts.h头文件的情况下,程序正常运行。

我不明白为什么当我将它移动到类文件时会发生这种情况。这是.pro文件和错误:

的.pro:

# Add more folders to ship with the application, here
folder_01.source = qml/GC
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01

# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =

# If your application uses the Qt Mobility libraries, uncomment the following
# lines and add the respective components to the MOBILITY variable.
# CONFIG += mobility
# MOBILITY +=

# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp \
    simkeyevent.cpp \
    serialthread.cpp \
    serial.cpp \
    tts.cpp

# Installation path
# target.path =

# Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()

#Manually added:
QT += core gui serialport

HEADERS += \
    simkeyevent.h \
    serialthread.h \
    serial.h \
    tts.h

错误:

First errors

1 个答案:

答案 0 :(得分:1)

我会重构你的tts.h以转发声明ISpVoice接口,并删除所有依赖项;这也会大大减少编译时间。

#ifndef TTS_H
#define TTS_H

interface ISpVoice; // or struct ISpVoice, if GCC hates interface decls.

class Tts
{
public:
    Tts();
    bool Initialize();
    HRESULT Speak(char * text, ISpVoice * pVoice);

private:

};

#endif // TTS_H

或者,你的#include顺序有点奇怪;你在sapi.h之前是#including windows.h,并且两者之间存在一些依赖关系。尝试颠倒它们。

您将错误列表中的行号留下,但看起来初始错误在sapi.h中的这一行:

typedef interface ISpNotifySource ISpNotifySource;

所以我怀疑GCC在使用interface关键字时遇到了一些问题,而其他一些头文件正在屏蔽它。