📄 ttsdlg.cpp.bak
字号:
// 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 + -