⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttsdlg.cpp.bak

📁 TTS语音开发示例
💻 BAK
📖 第 1 页 / 共 2 页
字号:
// TTSDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TTS.h"
#include "TTSDlg.h"
#include <io.h>

//using namespace std;

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//Interphonic 序列号
char g_SerialNo[]="P4GM29-QC4LXX-NAN6BF";

extern int bSTTSApiLoaded;

//本结构用来传递合成参数到线程中
typedef struct tTHREADPARAM{
	int nCodePage;//内码
	int nSpeed;//合成语速
	int nAudioFmt;//音频格式
	TCHAR* szSource;//源文本,可以是字符串或者文本文件
	TCHAR* szDest;//目标音频文件,可以为空,自动生成
	BOOL bString;//标识szSource是待合成字符串还是文本路径,如果为真,则传入的是字符串
}THREADPARAM;

// CTTSDlg dialog


CTTSDlg::CTTSDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTTSDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_timer = 1;
	m_isStart = false;
	m_speed = 0;
}

void CTTSDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CTTSDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_START, &CTTSDlg::OnPlay)
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CTTSDlg message handlers

BOOL CTTSDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	int res;
	res = InitSapi();
	if(res == -1)
		exit(-1);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTTSDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//初始化Speech SDK
HRESULT CTTSDlg::InitSapi()
{
	DWORD dwErr;
	char szInfo[255];
	char *strIP = NULL;

	//装载STTSApi.dll和iFlyTTS.dll
	if(!STTSLoadLibrary()) {
		dwErr=GetLastError();
		AfxMessageBox(_T("不能装载STTSApi.dll"));
		return -1;
	}
	//初始化声音合成接口
	if(!(m_isInit=STTSInit())) {
		//得到错误代码
		dwErr = GetLastError();
		if ( dwErr != TTSERR_OK ) {
			if ( TTSGETERRCODE(dwErr) == TTSERR_NOLICENCE ) {
				sprintf(szInfo, "初始化TTS失败, 错误原因: 没有正确的授权。");
			}
			else {
				sprintf(szInfo, "初始化TTS失败, 错误代号: %d。", dwErr);
			}
			AfxMessageBox( CString(szInfo), MB_OK|MB_ICONSTOP );
		}
		return -1;
	}

	//连接TTS服务器
	if(!(m_hTTSInstance=STTSConnect( g_SerialNo, strIP ))) {
		//用GetLastError()来得到出错原因
		dwErr=GetLastError();
		if ( dwErr != TTSERR_OK )
		{
			if( TTSGETERRCODE(dwErr) == TTSERR_INVALIDSN ) {
				sprintf(szInfo, "连接TTS服务失败, 错误原因: 错误的序列号。");
			}
			else if ( TTSGETERRCODE(dwErr) == TTSERR_NOLICENCE ) {
				sprintf(szInfo, "连接TTS服务失败, 错误原因: 没有足够的授权。");
			}
			else {
				sprintf(szInfo, "连接TTS服务失败, errorcode: 0x00%x", TTSGETERRCODE(dwErr));
			}
			
			AfxMessageBox(CString(szInfo), MB_OK|MB_ICONSTOP);
		}
		return -1;
	}
	//设置文字编码方式
	STTSSetParam(m_hTTSInstance,TTS_PARAM_CODEPAGE,1);
	STTSSetParam(m_hTTSInstance,TTS_PARAM_AUDIODATAFMT,0);
	return 0;
}

//释放Speech SDK
void CTTSDlg::ReleaseSapi()
{
	//释放TTS连接
	STTSDisconnect(m_hTTSInstance);
	//回收工作
	if(bSTTSApiLoaded) {	
		//释放TTS
		if(m_isInit) {
			STTSDeinit();
			m_isInit=FALSE;
		}
		//卸载TTS DLL
		STTSUnloadLibrary();
		bSTTSApiLoaded=FALSE;
	}
}

HCURSOR CTTSDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
//处理输入的文本,进行断句
void CTTSDlg::LoadPage(const string filename)
{
	ifstream file(filename.c_str());
	char c, d;

	
	c = file.get();
	string sentence;

	if(c == EOF)		//如果为一个空文本
	{			
		sentence = string("当前放入的是空白纸张或无法识别的纸张,请重新放置.");
		m_page.push_back(sentence);
		file.close();
		m_senPos = m_page.begin();
		return;
	}
	else if((c & 0x80) == 0)		//第一个字符为英文字符
	{
		m_page.push_back("朗读开始。");		//在开头加入朗读开始
		if(c != 34)					//去除引号
			sentence.push_back(c);
	}
	else if((c & 0x80) != 0)			//第一个字符为中文字符
	{
		m_page.push_back("朗读开始。");
		d = file.get();
		if(c != -95 || (c == -95 && (d != -80 && d != -79)))	//去除引号
		{
			sentence.push_back(c);
			sentence.push_back(d);
		}
	}
	//读取文本循环
	while((c = file.get()) != EOF)
	{
		if(c == 10)			//回车按照一个句号处理,作为断句标识
		{
			//string temp = "";
			//for(int i = 0; i < sentence.length(); i++)
			//{
			//	if(sentence.at(i) != ' ')
			//		temp.push_back(sentence.at(i));
			//}
			//if(temp.length() == 0)
			//{
			//	sentence.clear();
			//	continue;
			//}
			//else
			//{
			//	m_page.push_back(sentence);
			//	sentence.clear();
			//}
			continue;
		}
		else if((c & 0x80) == 0)		//处理英文字符
		{
			if(c == 34)				//引号排除
				continue;
			else if((c == 33 || c == 63) && sentence.length() == 0)	//多个问号或者叹号只处理第一个
				continue;
			sentence.push_back(c);
			if(c == 33 || c == 63)		//问号或者叹号时
			{
				m_page.push_back(sentence);
				sentence.clear();
			}
		}
		else if((c & 0x80) > 0)		//处理中文字符
		{
			d = file.get();
			if(c == -95 && (d == -80 || d == -79))		//处理引号
				continue;
			else if(c == -93 && (d == -95 || d == -65) && sentence.length() == 0)	//处理多个问号或者感叹号
				continue;
			else if(c == -95 && d == -93 && sentence.length() == 0)
				continue;
			else if(c == -93 && (d == -88 || d == -87))		//处理括号
				continue;

			sentence.push_back(c);
			sentence.push_back(d);
			if(c == -95 && d == -93)		//句号断句
			{
				string temp = "";
				for(unsigned i = 0; i < sentence.length(); i++)
				{
					if(sentence.at(i) != ' ')
						temp.push_back(sentence.at(i));
				}
				if(temp.length() > 6)
				{
					m_page.push_back(temp);
					sentence.clear();
				}
				//sentence = temp;
				//temp.clear();
				continue;
			}
			else if(c == -93 && d == -95)	//感叹号断句
			{
				string temp = "";
				for(unsigned i = 0; i < sentence.length(); i++)
				{
					if(sentence.at(i) != ' ')
						temp.push_back(sentence.at(i));
				}
				if(temp.length() > 6)
				{
					m_page.push_back(temp);
					sentence.clear();
				}
				continue;
			}
			else if(c == -93 && d == -65)	//问号断句
			{
				string temp = "";
				for(unsigned i = 0; i < sentence.length(); i++)
				{
					if(sentence.at(i) != ' ')
						temp.push_back(sentence.at(i));
				}
				if(temp.length() > 6)
				{
					m_page.push_back(temp);
					sentence.clear();
				}
				continue;
			}

		}
	}

	if(!sentence.empty())
		m_page.push_back(sentence);
	m_page.push_back("朗读结束, 按暂停/虫读键重新听一遍,按返回键继续操作。");
	file.close();
	m_senPos = m_page.begin();

}
//播放音频
void CTTSDlg::OnPlay()
{
	//关闭定时器
	KillTimer(m_timer);

	if(m_senPos == m_page.end())
	{
		m_isStart = false;
		return;
	}
	m_isStop = false;
	m_isPause = false;

	STTSSetParam(m_hTTSInstance,TTS_PARAM_SPEED,m_speed);
	
	m_timer=SetTimer(1,300,NULL);
	//STTSGetParam(m_hTTSInstance,TTS_PARAM_AUDIODATAFMT,&nAudioFmt);
	STTSPlayString(m_hTTSInstance, (char*)m_senPos->c_str(), 1);
	//STTSDisconnect(hTTSInstance);
}

//恢复或者暂停语音
void CTTSDlg::OnPause()
{
	if(!m_isPause)	//当前正在播放,暂停播放
	{
		KillTimer(m_timer);
		STTSPlayStop();
		m_isPause = true;
	}
	else			//当前已经暂停,恢复播放
	{
		m_isPause = false;
		OnPlay();
	}
}

//停止当前读音
void CTTSDlg::OnStop()
{
	KillTimer(m_timer);
	m_isStop = true;
	STTSPlayStop();
	m_senPos = m_page.begin();
	m_speed = 0;
	m_isStart = false;
}

//增加语速
void CTTSDlg::OnIncreaseRate()
{
	KillTimer(m_timer);
	if(m_speed <= 500)
		m_speed += 100;
	m_timer=SetTimer(1,500,NULL);
}

//降低语速
void CTTSDlg::OnDecreaseRate()
{
	KillTimer(m_timer);
	if(m_speed >= -500)
		m_speed -= 100;
	m_timer=SetTimer(1,500,NULL);
}

//获取键盘输入
BOOL CTTSDlg::PreTranslateMessage(MSG* pMsg)
{
	if(pMsg->message == WM_KEYDOWN)
	{
		switch(pMsg->wParam)
		{
		case VK_DIVIDE:		//返回建/
			if(!m_isStop)
				OnStop();
			break;
		case 99:			//快退3
			if(m_senPos == m_page.end())
			{
				KillTimer(m_timer);
				STTSPlayStop();
				m_senPos--;
				m_senPos--;
				m_isStart = true;
				OnPlay();
			}
			else if(m_senPos != m_page.begin())
			{
				KillTimer(m_timer);
				STTSPlayStop();
				m_senPos--;
				OnPlay();
			}
			break;
		case VK_DECIMAL:		//快进。
			if(m_senPos != m_page.end())
			{
				KillTimer(m_timer);
				STTSPlayStop();
				m_senPos++;
				OnPlay();
			}
			break;
		case 102:				//减速6
			OnDecreaseRate();
			break;
		case 105:				//加速9
			OnIncreaseRate();
			break;
		case VK_ADD:			//暂停键
			if(!m_isStart)
			{
				if(!m_isLoad)		//不读取存储文本
				{
					m_senPos = m_page.begin();
					OnPlay();
					m_isStart = true;
					m_isStop = false;
				}
				else				//读取存储文本
				{
					LoadSavedPage();
					OnPlay();
					m_isStart = true;
					m_isStop = false;
				}
			}
			else
				OnPause();
			break;
		case 100:			// 4 前一本书
			if(m_isCover)
				m_isCover = false;
			PreBook();
			break;
		case 101:			//	5 后一本书
			if(m_isCover)
				m_isCover = false;
			NextBook();
			break;
		case 97:			// 1 前一页
			if(m_isCover)
				m_isCover = false;
			PrePage();
			break;
		case 98:			// 2 后一页
			if(m_isCover)
				m_isCover = false;
			NextPage();
			break;
		case 96:			// 0 录入
			if(m_isDelete)
				m_isDelete = false;
			CheckSavePage();
			break;
		case VK_BACK:		//删除
			if(m_isSave)
			{
				m_isSave = false;
				m_isCover = false;
			}
			CheckDelete();
			break;
		default:
			break;
		};
	}

	return CDialog::PreTranslateMessage(pMsg);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -