C++ 一种隐藏类成员变量的设计实现 TTS语音播报模块
前言
例如:c++类隐藏成员变量,通过基类暴露接口,供其他模块调用使用
本文,主要通过TTS语音播报模块介绍
提示:以下是本篇文章正文内容,下面案例可供参考
一、类的定义
基类CTTSBase:
#include <string>
class CTTSBase
{
public:
CTTSBase() {};
virtual ~CTTSBase() {};
virtual bool Speak(std::string)=0;
};
子类CTTSImpl.h:
#pragma once
#include "CTTSBase.h"
#include "sapi.h"
#include <list>
#include <string>
#include "sphelper.h"
#pragma comment(lib, "sapi.lib")
class CTTSImpl :
public CTTSBase
{
public:
CTTSImpl();
virtual ~CTTSImpl();
virtual bool Speak(std::string);
bool IsUseful();
private:
ISpVoice* m_pSpVoice = nullptr;
bool Init = false;
bool InitVoice();
void StopVoice();
};
子类CTTSImpl.cpp:
#include "pch.h"
#include "CTTSImpl.h"
#include "CWordHelper.h"
CTTSImpl::CTTSImpl()
:m_pSpVoice(nullptr)
{
}
CTTSImpl::~CTTSImpl()
{
StopVoice();
::CoUninitialize();
}
std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
{
int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
if (nSize <= 0)
return std::wstring();
WCHAR* pwszDst = new WCHAR[nSize + 1];
if (NULL == pwszDst)
return NULL;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, pwszDst, nSize);
pwszDst[nSize] = 0;
if (pwszDst[0] == 0xFEFF) // skip Oxfeff
for (int i = 0; i < nSize; i++)
pwszDst[i] = pwszDst[i + 1];
std::wstring wcharString(pwszDst);
delete []pwszDst;
return wcharString;
}
bool CTTSImpl::Speak(std::string word)
{
StopVoice();
if (InitVoice())
{
CWordHelper::Relace(word);
std::wstring wsword = Ansi2WChar(word.c_str(), word.size());
HRESULT ret = m_pSpVoice->Speak(wsword.c_str(), SPF_ASYNC, NULL);
return ret==S_OK;
}
else
{
return false;
}
}
bool CTTSImpl::IsUseful()
{
return false;
}
bool CTTSImpl::InitVoice()
{
HRESULT ret = ::CoInitialize(NULL);
ret = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER, IID_ISpVoice, (void**)&m_pSpVoice);
if (0 == ret && m_pSpVoice)
{
m_pSpVoice->SetVolume(80);
IEnumSpObjectTokens* pSpEnumTokens = NULL;
if (SUCCEEDED(SpEnumTokens(SPCAT_VOICES, NULL, NULL, &pSpEnumTokens))) //找到lili语音进行朗读, 否则就跳出
{
ISpObjectToken* pSpToken = NULL;
while (SUCCEEDED(pSpEnumTokens->Next(1, &pSpToken, NULL)) && pSpToken != NULL)
{
LPWSTR pId = new WCHAR[32];
pSpToken->GetId(&pId);
int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pId, -1, NULL, 0, NULL, NULL);
char* s = new char[nLen + 1];
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pId, -1, s, nLen, NULL, NULL);
if (0 == strcmp(s, ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices\\Tokens\\MS-Lili-2052-20-DSK")))
{
m_pSpVoice->SetVoice(pSpToken); // 设置lili语音
pSpToken->Release();
delete[] s;
break;
}
delete[] s;
pSpToken->Release();
}
pSpEnumTokens->Release();
}
return true;
}
else
{
}
return false;
//————————————————
// 版权声明:本文为CSDN博主「32131532」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
// 原文链接:https ://blog.csdn.net/lvwenshuai/article/details/131538906
}
CWordHelper:
#pragma once
#include<string>
class CWordHelper
{
public:
static void Relace(std::string& s );
};
---------------------------------------------
#include "pch.h"
#include "CWordHelper.h"
#include <map>
#include <unordered_map>
std::unordered_map<std::string , std::string> mapReplace=
{
{"1","幺"}, {"2","二"}, {"3","三"}, {"4","四"},
{"5","五"}, {"6","六"}, {"7","拐"}, {"8","八"},
{"9","九"}, {"0","洞"}, {"-","杠"}, {".","点"},
/* {"/","左斜杠"},*/
};
void CWordHelper::Relace(std::string& s)
{
for (auto iter : mapReplace)
{
size_t pos = s.find(iter.first);
while (pos != std::string::npos) {
s.replace(pos, 1, iter.second);
pos = s.find(iter.first);
}
}
}
二、导出类和接口封装
class TTSDLL_API CTTSFactory
{
public:
static CTTSBase* GetModuleInstance();
};
TTSDLL_API void TTS_Speak(std::string str);
CTTSBase* CTTSFactory::GetModuleInstance()
{
static CTTSImpl InStance;
return &InStance;
}
TTSDLL_API void TTS_Speak(std::string str)
{
CTTSFactory::GetModuleInstance()->Speak(str);
}
三、使用
#include <iostream>
#include"../TTSDLL/TTSModuleDll.h"
#include<thread>
int main()
{
std::thread t([]()
{
TTS_Speak("123456");
});
t.detach();
system("pause");
}
void CTTSApplicationDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString szText;
GetDlgItem(IDC_EDIT1)->GetWindowText(szText);
/// <summary>
/// 导出类
/// </summary>
CTTSFactory::GetModuleInstance()->Speak(std::string(szText));
}
四、总结
资源Demo已上传