【c++语音播报模块的封装与使用】

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已上传
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值