日本关东景点哪些:文字转语音TTSDlg.cpp

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 20:31:48

TTS-code.rar TTSDlg.cpp  

2010-11-02 09:09:58|  分类: 默认分类 |字号 订阅

  1. // TTSDlg.cpp : implementation file    
  2. //    
  3.    
  4. #include "stdafx.h"    
  5. #include "TTS.h"    
  6. #include "TTSDlg.h"    
  7. #include     
  8. #include     
  9. //using namespace std;    
  10.    
  11. #ifdef _DEBUG    
  12. #define new DEBUG_NEW    
  13. #endif    
  14.    
  15. //Interphonic 序列号    
  16. char g_SerialNo[]="P4GM29-QC4LXX-NAN6BF";   
  17.    
  18. extern int bSTTSApiLoaded;   
  19.    
  20. //本结构用来传递合成参数到线程中    
  21. typedef struct tTHREADPARAM{   
  22.     int nCodePage;//内码    
  23.     int nSpeed;//合成语速    
  24.     int nAudioFmt;//音频格式    
  25.     TCHAR* szSource;//源文本,可以是字符串或者文本文件    
  26.     TCHAR* szDest;//目标音频文件,可以为空,自动生成    
  27.     BOOL bString;//标识szSource是待合成字符串还是文本路径,如果为真,则传入的是字符串    
  28. }THREADPARAM;   
  29.    
  30. // CTTSDlg dialog    
  31.    
  32.    
  33. CTTSDlg::CTTSDlg(CWnd* pParent /*=NULL*/)   
  34.     : CDialog(CTTSDlg::IDD, pParent)   
  35. {   
  36.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);   
  37.     m_timer = 1;   
  38.     m_isStart = false;   
  39.     m_speed = 0;   
  40. }   
  41.    
  42. CTTSDlg::~CTTSDlg()   
  43. {   
  44.     SaveIndex();   
  45. }   
  46.    
  47. void CTTSDlg::DoDataExchange(CDataExchange* pDX)   
  48. {   
  49.     CDialog::DoDataExchange(pDX);   
  50. }   
  51.    
  52. BEGIN_MESSAGE_MAP(CTTSDlg, CDialog)   
  53.     ON_WM_PAINT()   
  54.     ON_WM_QUERYDRAGICON()   
  55.     //}}AFX_MSG_MAP    
  56.     ON_BN_CLICKED(IDC_START, &CTTSDlg::OnPlay)   
  57.     ON_WM_TIMER()   
  58. END_MESSAGE_MAP()   
  59.    
  60.    
  61. // CTTSDlg message handlers    
  62.    
  63. BOOL CTTSDlg::OnInitDialog()   
  64. {   
  65.     CDialog::OnInitDialog();   
  66.    
  67.     // Set the icon for this dialog.  The framework does this automatically    
  68.     //  when the application's main window is not a dialog    
  69.     SetIcon(m_hIcon, TRUE);         // Set big icon    
  70.     SetIcon(m_hIcon, FALSE);        // Set small icon    
  71.     int res;   
  72.     res = InitSapi();   
  73.     if(res == -1)   
  74.         exit(-1);   
  75.     LoadPage(string("D:\\TTS.txt"));   
  76.    
  77.     InitIndex();   
  78.     return TRUE;  // return TRUE  unless you set the focus to a control    
  79. }   
  80.    
  81. void CTTSDlg::OnPaint()   
  82. {   
  83.     if (IsIconic())   
  84.     {   
  85.         CPaintDC dc(this); // device context for painting    
  86.    
  87.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);   
  88.    
  89.         // Center icon in client rectangle    
  90.         int cxIcon = GetSystemMetrics(SM_CXICON);   
  91.         int cyIcon = GetSystemMetrics(SM_CYICON);   
  92.         CRect rect;   
  93.         GetClientRect(&rect);   
  94.         int x = (rect.Width() - cxIcon + 1) / 2;   
  95.         int y = (rect.Height() - cyIcon + 1) / 2;   
  96.    
  97.         // Draw the icon    
  98.         dc.DrawIcon(x, y, m_hIcon);   
  99.     }   
  100.     else   
  101.     {   
  102.         CDialog::OnPaint();   
  103.     }   
  104. }   
  105.    
  106. //初始化Speech SDK    
  107. HRESULT CTTSDlg::InitSapi()   
  108. {   
  109.     DWORD dwErr;   
  110.     char szInfo[255];   
  111.     char *strIP = NULL;   
  112.    
  113.     //装载STTSApi.dll和iFlyTTS.dll    
  114.     if(!STTSLoadLibrary()) {   
  115.         dwErr=GetLastError();   
  116.         AfxMessageBox(_T("不能装载STTSApi.dll"));   
  117.         return -1;   
  118.     }   
  119.     //初始化声音合成接口    
  120.     if(!(m_isInit=STTSInit())) {   
  121.         //得到错误代码    
  122.         dwErr = GetLastError();   
  123.         if ( dwErr != TTSERR_OK ) {   
  124.             if ( TTSGETERRCODE(dwErr) == TTSERR_NOLICENCE ) {   
  125.                 sprintf(szInfo, "初始化TTS失败, 错误原因: 没有正确的授权。");   
  126.             }   
  127.             else {   
  128.                 sprintf(szInfo, "初始化TTS失败, 错误代号: %d。", dwErr);   
  129.             }   
  130.             AfxMessageBox( CString(szInfo), MB_OK|MB_ICONSTOP );   
  131.         }   
  132.         return -1;   
  133.     }   
  134.    
  135.     //连接TTS服务器    
  136.     if(!(m_hTTSInstance=STTSConnect( g_SerialNo, strIP ))) {   
  137.         //用GetLastError()来得到出错原因    
  138.         dwErr=GetLastError();   
  139.         if ( dwErr != TTSERR_OK )   
  140.         {   
  141.             if( TTSGETERRCODE(dwErr) == TTSERR_INVALIDSN ) {   
  142.                 sprintf(szInfo, "连接TTS服务失败, 错误原因: 错误的序列号。");   
  143.             }   
  144.             else if ( TTSGETERRCODE(dwErr) == TTSERR_NOLICENCE ) {   
  145.                 sprintf(szInfo, "连接TTS服务失败, 错误原因: 没有足够的授权。");   
  146.             }   
  147.             else {   
  148.                 sprintf(szInfo, "连接TTS服务失败, errorcode: 0x00%x", TTSGETERRCODE(dwErr));   
  149.             }   
  150.                
  151.             AfxMessageBox(CString(szInfo), MB_OK|MB_ICONSTOP);   
  152.         }   
  153.         return -1;   
  154.     }   
  155.     //设置文字编码方式    
  156.     STTSSetParam(m_hTTSInstance,TTS_PARAM_CODEPAGE,1);   
  157.     STTSSetParam(m_hTTSInstance,TTS_PARAM_AUDIODATAFMT,0);   
  158.     return 0;   
  159. }   
  160.    
  161. //释放Speech SDK    
  162. void CTTSDlg::ReleaseSapi()   
  163. {   
  164.     //释放TTS连接    
  165.     STTSDisconnect(m_hTTSInstance);   
  166.     //回收工作    
  167.     if(bSTTSApiLoaded) {       
  168.         //释放TTS    
  169.         if(m_isInit) {   
  170.             STTSDeinit();   
  171.             m_isInit=FALSE;   
  172.         }   
  173.         //卸载TTS DLL    
  174.         STTSUnloadLibrary();   
  175.         bSTTSApiLoaded=FALSE;   
  176.     }   
  177. }   
  178.    
  179. HCURSOR CTTSDlg::OnQueryDragIcon()   
  180. {   
  181.     return static_cast(m_hIcon);   
  182. }   
  183. //处理输入的文本,进行断句    
  184. void CTTSDlg::LoadPage(const string filename)   
  185. {   
  186.     ifstream file(filename.c_str());   
  187.     char c, d;   
  188.    
  189.        
  190.     c = file.get();   
  191.     string sentence;   
  192.    
  193.     if(c == EOF)        //如果为一个空文本    
  194.     {              
  195.         sentence = string("当前放入的是空白纸张或无法识别的纸张,请重新放置.");   
  196.         m_page.push_back(sentence);   
  197.         file.close();   
  198.         m_senPos = m_page.begin();   
  199.         return;   
  200.     }   
  201.     else if((c & 0x80) == 0)        //第一个字符为英文字符    
  202.     {   
  203.         m_page.push_back("朗读开始。");      //在开头加入朗读开始    
  204.         if(c != 34)                 //去除引号    
  205.             sentence.push_back(c);   
  206.     }   
  207.     else if((c & 0x80) != 0)            //第一个字符为中文字符    
  208.     {   
  209.         m_page.push_back("朗读开始。");   
  210.         d = file.get();   
  211.         if(c != -95 || (c == -95 && (d != -80 && d != -79)))    //去除引号    
  212.         {   
  213.             sentence.push_back(c);   
  214.             sentence.push_back(d);   
  215.         }   
  216.     }   
  217.     //读取文本循环    
  218.     while((c = file.get()) != EOF)   
  219.     {   
  220.         if(m_page.size() == 1 && c == 10)           //回车按照一个句号处理,作为断句标识    
  221.         {   
  222.             string temp = "";   
  223.             for(unsigned i = 0; i < sentence.length(); i++)   
  224.             {   
  225.                 if(sentence.at(i) != ' ')   
  226.                     temp.push_back(sentence.at(i));   
  227.             }   
  228.             if(temp.length() == 0)   
  229.             {   
  230.                 sentence.clear();   
  231.                 continue;   
  232.             }   
  233.             else   
  234.             {   
  235.                 m_page.push_back(sentence);   
  236.                 sentence.clear();   
  237.             }   
  238.             continue;   
  239.         }   
  240.         //2007.5.15修改    
  241.         else if(c == 10)   
  242.             continue;   
  243.         else if((c & 0x80) == 0)        //处理英文字符    
  244.         {   
  245.             if(c == 34)             //引号排除    
  246.                 continue;   
  247.             else if((c == 33 || c == 63) && sentence.length() == 0) //多个问号或者叹号只处理第一个    
  248.                 continue;   
  249.             sentence.push_back(c);   
  250.             if((c == 33 || c == 63) && sentence.length() > 6)        //问号或者叹号时    
  251.             {   
  252.                 m_page.push_back(sentence);   
  253.                 sentence.clear();   
  254.             }   
  255.         }   
  256.         else if((c & 0x80) > 0)      //处理中文字符    
  257.         {   
  258.             d = file.get();   
  259.             if(c == -95 && (d == -80 || d == -79))      //处理引号    
  260.                 continue;   
  261.             else if(c == -93 && (d == -95 || d == -65) && sentence.length() == 0)   //处理多个问号或者感叹号    
  262.                 continue;   
  263.             else if(c == -95 && d == -93 && sentence.length() == 0)   
  264.                 continue;   
  265.             else if(c == -93 && (d == -88 || d == -87))     //处理括号    
  266.                 continue;   
  267.    
  268.             sentence.push_back(c);   
  269.             sentence.push_back(d);   
  270.             if(c == -95 && d == -93)        //句号断句    
  271.             {   
  272.                 string temp = "";   
  273.                 for(unsigned i = 0; i < sentence.length(); i++)   
  274.                 {   
  275.                     if(sentence.at(i) != ' ')   
  276.                         temp.push_back(sentence.at(i));   
  277.                 }   
  278.                 if(temp.length() > 6)   
  279.                 {   
  280.                     m_page.push_back(temp);   
  281.                     sentence.clear();   
  282.                 }   
  283.                 //sentence = temp;    
  284.                 //temp.clear();    
  285.                 continue;   
  286.             }   
  287.             else if(c == -93 && d == -95)   //感叹号断句    
  288.             {   
  289.                 string temp = "";   
  290.                 for(unsigned i = 0; i < sentence.length(); i++)   
  291.                 {   
  292.                     if(sentence.at(i) != ' ')   
  293.                         temp.push_back(sentence.at(i));   
  294.                 }   
  295.                 if(temp.length() > 6)   
  296.                 {   
  297.                     m_page.push_back(temp);   
  298.                     sentence.clear();   
  299.                 }   
  300.                 continue;   
  301.             }   
  302.             else if(c == -93 && d == -65)   //问号断句    
  303.             {   
  304.                 string temp = "";   
  305.                 for(unsigned i = 0; i < sentence.length(); i++)   
  306.                 {   
  307.                     if(sentence.at(i) != ' ')   
  308.                         temp.push_back(sentence.at(i));   
  309.                 }   
  310.                 if(temp.length() > 6)   
  311.                 {   
  312.                     m_page.push_back(temp);   
  313.                     sentence.clear();   
  314.                 }   
  315.                 continue;   
  316.             }   
  317.    
  318.         }   
  319.     }   
  320.    
  321.     if(!sentence.empty())   
  322.         m_page.push_back(sentence);   
  323.     m_page.push_back("朗读结束, 按暂停/虫读键重新听一遍,按返回键继续操作。");   
  324.     file.close();   
  325.     m_senPos = m_page.begin();   
  326.    
  327. }   
  328. //播放音频    
  329. void CTTSDlg::OnPlay()   
  330. {   
  331.     //关闭定时器    
  332.     KillTimer(m_timer);   
  333.    
  334.     if(m_senPos == m_page.end())   
  335.     {   
  336.         m_isStart = false;   
  337.         return;   
  338.     }   
  339.    
  340.     m_isStop = false;   
  341.     m_isPause = false;   
  342.    
  343.     STTSSetParam(m_hTTSInstance,TTS_PARAM_SPEED,m_speed);   
  344.        
  345.     m_timer=SetTimer(1,300,NULL);   
  346.     //STTSGetParam(m_hTTSInstance,TTS_PARAM_AUDIODATAFMT,&nAudioFmt);    
  347.     STTSPlayString(m_hTTSInstance, (char*)m_senPos->c_str(), 1);   
  348.     //STTSDisconnect(hTTSInstance);    
  349. }   
  350.    
  351. //恢复或者暂停语音    
  352. void CTTSDlg::OnPause()   
  353. {   
  354.     if(!m_isPause)  //当前正在播放,暂停播放    
  355.     {   
  356.         KillTimer(m_timer);   
  357.         STTSPlayStop();   
  358.         m_isPause = true;   
  359.     }   
  360.     else            //当前已经暂停,恢复播放    
  361.     {   
  362.         m_isPause = false;   
  363.         OnPlay();   
  364.     }   
  365. }   
  366.    
  367. //停止当前读音    
  368. void CTTSDlg::OnStop()   
  369. {   
  370.     KillTimer(m_timer);   
  371.     m_isStop = true;   
  372.     STTSPlayStop();   
  373.     m_senPos = m_page.begin();   
  374.     m_speed = 0;   
  375.     m_isStart = false;   
  376. }   
  377.    
  378. //增加语速    
  379. void CTTSDlg::OnIncreaseRate()   
  380. {   
  381.     KillTimer(m_timer);   
  382.     if(m_speed <= 500)   
  383.         m_speed += 100;   
  384.     m_timer=SetTimer(1,500,NULL);   
  385. }   
  386.    
  387. //降低语速    
  388. void CTTSDlg::OnDecreaseRate()   
  389. {   
  390.     KillTimer(m_timer);   
  391.     if(m_speed >= -500)   
  392.         m_speed -= 100;   
  393.     m_timer=SetTimer(1,500,NULL);   
  394. }   
  395.    
  396. //获取键盘输入    
  397. BOOL CTTSDlg::PreTranslateMessage(MSG* pMsg)   
  398. {   
  399.     if(pMsg->message == WM_KEYDOWN)   
  400.     {   
  401.         switch(pMsg->wParam)   
  402.         {   
  403.         case VK_DIVIDE:     //返回建/    
  404.             if(!m_isStop)   
  405.                 OnStop();   
  406.             break;   
  407.         case 99:            //快退3    
  408.             if(m_senPos == m_page.end())   
  409.             {   
  410.                 KillTimer(m_timer);   
  411.                 STTSPlayStop();   
  412.                 m_senPos--;   
  413.                 m_senPos--;   
  414.                 m_isStart = true;   
  415.                 OnPlay();   
  416.             }   
  417.             else if(m_senPos != m_page.begin())   
  418.             {   
  419.                 KillTimer(m_timer);   
  420.                 STTSPlayStop();   
  421.                 m_senPos--;   
  422.                 OnPlay();   
  423.             }   
  424.             break;   
  425.         case VK_DECIMAL:        //快进。    
  426.             if(m_senPos != m_page.end())   
  427.             {   
  428.                 KillTimer(m_timer);   
  429.                 STTSPlayStop();   
  430.                 m_senPos++;   
  431.                 OnPlay();   
  432.             }   
  433.             break;   
  434.         case 102:               //减速6    
  435.             OnDecreaseRate();   
  436.             break;   
  437.         case 105:               //加速9    
  438.             OnIncreaseRate();   
  439.             break;   
  440.         case VK_ADD:            //暂停键    
  441.             if(!m_isStart)   
  442.             {   
  443.                 if(!m_isLoad)       //不读取存储文本    
  444.                 {   
  445.                     m_senPos = m_page.begin();   
  446.                     m_isStart = true;   
  447.                     m_isStop = false;   
  448.                     OnPlay();   
  449.                 }   
  450.                 else                //读取存储文本    
  451.                 {   
  452.                     LoadSavedPage();   
  453.                     m_isStart = true;   
  454.                     m_isStop = false;   
  455.                     OnPlay();   
  456.                 }   
  457.             }   
  458.             else   
  459.                 OnPause();   
  460.             break;   
  461.         case 100:           // 4 前一本书    
  462.             if(m_isCover)   
  463.                 m_isCover = false;   
  464.             if(m_isStart)   
  465.             {   
  466.                 m_isStart = false;   
  467.                 m_isStop = true;   
  468.             }   
  469.             STTSPlayStop();   
  470.             PreBook();   
  471.             break;   
  472.         case 101:           //  5 后一本书    
  473.             if(m_isCover)   
  474.                 m_isCover = false;   
  475.             if(m_isStart)   
  476.             {   
  477.                 m_isStart = false;   
  478.                 m_isStop = true;   
  479.             }   
  480.             STTSPlayStop();   
  481.             NextBook();   
  482.             break;   
  483.         case 97:            // 1 前一页    
  484.             if(m_isCover)   
  485.                 m_isCover = false;   
  486.             if(m_isStart)   
  487.             {   
  488.                 m_isStart = false;   
  489.                 m_isStop = true;   
  490.             }   
  491.             STTSPlayStop();   
  492.             PrePage();   
  493.             break;   
  494.         case 98:            // 2 后一页    
  495.             if(m_isCover)   
  496.                 m_isCover = false;   
  497.             if(m_isStart)   
  498.             {   
  499.                 m_isStart = false;   
  500.                 m_isStop = true;   
  501.             }   
  502.             STTSPlayStop();   
  503.             NextPage();   
  504.             break;   
  505.         case 96:            // 0 录入    
  506.             if(m_isDelete)   
  507.                 m_isDelete = false;   
  508.             if(m_isStart)   
  509.             {   
  510.                 m_isStart = false;   
  511.                 m_isStop = true;   
  512.             }   
  513.             STTSPlayStop();   
  514.             CheckSavePage();   
  515.             break;   
  516.         case VK_BACK:       //删除 BackSpace    
  517.             if(m_isSave)   
  518.             {   
  519.                 m_isSave = false;   
  520.                 m_isCover = false;   
  521.             }   
  522.             if(m_isStart)   
  523.             {   
  524.                 m_isStart = false;   
  525.                 m_isStop = true;   
  526.             }   
  527.             STTSPlayStop();   
  528.             CheckDelete();   
  529.             break;   
  530.         case VK_SUBTRACT:       //帮助文件 '-'    
  531.             STTSPlayStop();   
  532.             if(m_isDelete)   
  533.                 m_isDelete = false;   
  534.             if(m_isSave)   
  535.                 m_isSave = false;   
  536.             if(m_isLoad)   
  537.                 m_isLoad = false;   
  538.             m_isStop = true;   
  539.             m_isStart = false;   
  540.             STTSPlayTextFile(m_hTTSInstance, "D:/TTS-Help.txt", 1);   
  541.         default:   
  542.             break;   
  543.         };   
  544.     }   
  545.    
  546.     return CDialog::PreTranslateMessage(pMsg);   
  547. }   
  548.    
  549. void CTTSDlg::OnCancel()   
  550. {   
  551.        
  552.     CDialog::OnCancel();   
  553. }   
  554.    
  555. void CTTSDlg::OnOK()   
  556. {   
  557.     //CDialog::OnOK();    
  558. }   
  559.    
  560. void CTTSDlg::OnTimer(UINT_PTR nIDEvent)   
  561. {   
  562.     int status;   
  563.     STTSQueryPlayStatus(&status);   
  564.     if(status == 0 && m_senPos != m_page.end() && !m_isStop)    //读完一句话,且没有暂停或停止,读下一句    
  565.     {   
  566.         m_senPos++;   
  567.         OnPlay();   
  568.     }   
  569.     CDialog::OnTimer(nIDEvent);   
  570. }   
  571.    
  572.    
  573. void CTTSDlg::InitIndex()   
  574. {   
  575.     //初始化    
  576.     m_bookIndex.resize(1000);   
  577.     memset(m_readTag, 0, 1000);   
  578.     memset(m_saveTag, 0, 1000);   
  579.     m_isLoad = false;   
  580.     m_isSave = false;   
  581.     m_isCover = false;   
  582.     m_isDelete = false;   
  583.    
  584.     //this is the index data file    
  585.     ifstream file("D:/TTS-Data/index.dat");   
  586.     string line;   
  587.        
  588.     //初始化文件索引、阅读标记以及存储标记    
  589.     ::getline(file, line);   
  590.     //get the readTeg    
  591.     istringstream temp(line);   
  592.     temp >> m_lastReadBook >> m_lastSaveBook;   
  593.    
  594.     int bookNum = 0;   
  595.     while(::getline(file, line))   
  596.     {   
  597.         istringstream input(line);   
  598.         int readTag;   
  599.         int saveTag;   
  600.         string content;   
  601.    
  602.         input >> readTag >> saveTag >> content;   
  603.         m_bookIndex[bookNum] = content;   
  604.         m_readTag[bookNum] = readTag;   
  605.         m_saveTag[bookNum] = saveTag;   
  606.         bookNum++;   
  607.     }   
  608.    
  609.     //初始化中间变量, Book从0开始计数    
  610.     m_currentBook = m_lastReadBook;   
  611.     m_currentPage = m_readTag[m_lastReadBook];   
  612.     m_curSaveBook = m_lastSaveBook;   
  613.     m_curSavePage = m_saveTag[m_lastSaveBook];   
  614. }   
  615.    
  616. void CTTSDlg::NextBook()   
  617. {   
  618.     ostringstream readStr;   
  619.     if(m_isSave)        //当前为录制状态    
  620.     {   
  621.         if(m_curSaveBook != 999)   
  622.         {          
  623.             m_curSaveBook++;   
  624.             m_curSavePage = m_saveTag[m_curSaveBook];   
  625.    
  626.             readStr << "录制当前阅读的内容到第" << m_curSaveBook+1 << "本书。"   
  627.                 << m_bookIndex[m_curSaveBook] << "第" << m_saveTag[m_curSaveBook]+1   
  628.                 << "页。按录制键确认录制或选择其他书页";              
  629.         }   
  630.         else   
  631.             readStr << "已经到达最后一本书.";   
  632.     }   
  633.     else if(m_isDelete)     //当前为删除状态    
  634.     {   
  635.         if(m_currentBook != 999)   
  636.         {   
  637.             m_currentBook++;   
  638.             m_currentPage = 0;   
  639.             m_isDelBook = true;   
  640.    
  641.             readStr << "清除当前整书, 第"  << m_currentBook+1 << "本书"   
  642.                 << m_bookIndex[m_currentBook] << "是否确认"    
  643.                 << "或通过前后页选择要清除的页码";   
  644.         }   
  645.         else   
  646.             readStr << "已经到达最后一本书.";   
  647.     }   
  648.     else    //当前为阅读状态    
  649.     {   
  650.         m_isLoad = true;   
  651.         if(m_currentBook != 999)    //如果不是最后一本书    
  652.         {   
  653.             m_currentBook++;   
  654.             m_currentPage = m_readTag[m_currentBook];   
  655.                
  656.             if(m_bookIndex[m_currentBook].length() == 0)   
  657.                 readStr << "第" << m_currentBook+1 << "本书,该书为空白。";   
  658.             else   
  659.             {   
  660.                 readStr << "第" << m_currentBook+1 << "本书。" << m_bookIndex[m_currentBook]   
  661.                         << "当前读到第" << m_readTag[m_currentBook]+1 << "页";   
  662.             }                          
  663.         }   
  664.         else   
  665.             readStr << "已经到达最后一本书.";   
  666.     }   
  667.    
  668.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  669. }   
  670.    
  671. void CTTSDlg::PreBook()   
  672. {   
  673.     ostringstream readStr;   
  674.    
  675.     if(m_isSave)                //当前状态为录制    
  676.     {   
  677.         if(m_curSaveBook != 0)   
  678.         {      
  679.             m_curSaveBook--;   
  680.             m_curSavePage = m_saveTag[m_curSaveBook];   
  681.    
  682.             readStr << "录制当前阅读的内容到第" << m_curSaveBook+1 << "本书。"   
  683.                 << m_bookIndex[m_curSaveBook] << "第" << m_saveTag[m_curSaveBook]+1   
  684.                 << "页。按录制键确认录制或选择其他书页";   
  685.         }   
  686.         else   
  687.             readStr << "已经到达第一本书";   
  688.     }   
  689.     else if(m_isDelete)   
  690.     {   
  691.         if(m_currentBook != 0)   
  692.         {      
  693.             m_currentBook--;           
  694.             m_currentPage = 0;   
  695.             m_isDelBook = true;   
  696.    
  697.             readStr << "清除当前整书, 第"  << m_currentBook+1 << "本书"   
  698.                 << m_bookIndex[m_currentBook] << "是否确认"    
  699.                 << "或通过前后页选择要清除的页码";   
  700.         }   
  701.         else   
  702.             readStr << "已经到达第一本书";   
  703.     }   
  704.     else        //当前状态为阅读    
  705.     {   
  706.         m_isLoad = true;   
  707.         if(m_currentBook != 0)  //如果不是第一本书    
  708.         {   
  709.             m_currentBook--;   
  710.             m_currentPage = m_readTag[m_currentBook];   
  711.    
  712.             if(m_bookIndex[m_currentBook].length() == 0)   
  713.                 readStr << "第" << m_currentBook+1 << "本书,该书为空白。";   
  714.             else   
  715.             {   
  716.                 readStr << "第" << m_currentBook+1 << "本书。"   
  717.                     << m_bookIndex[m_currentBook] << "当前读到第"    
  718.                     << m_readTag[m_currentBook]+1 << "页";   
  719.             }   
  720.         }   
  721.         else   
  722.             readStr << "已经到达第一本书";   
  723.     }   
  724.    
  725.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  726. }   
  727.    
  728. void CTTSDlg::NextPage()   
  729. {   
  730.     ostringstream readStr;   
  731.     if(m_isSave)        //当前状态为录制状态    
  732.     {      
  733.         //该书为空白    
  734.         //if(m_bookIndex[m_curSaveBook].length() == 0)    
  735.         //{    
  736.         //  readStr << "该书为空白,录制当前阅读的内容到第" << m_curSavePage+1 << "页"    
  737.         //      << "请按录制键开始录制";    
  738.         //  STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);    
  739.         //  return;    
  740.         //}    
  741.         //if(m_curSavePage != 0)    
  742.         //  m_curSavePage++;    
  743.         m_curSavePage++;   
  744.         readStr << "录制当前阅读的内容到第" << m_curSavePage+1 << "页"   
  745.             << "按录制键确认录制或选择其他书页";   
  746.     }   
  747.     else if(m_isDelete)     //当前状态为删除状态    
  748.     {      
  749.         m_isDelBook = false;   
  750.         m_currentPage++;       
  751.         ostringstream pageName;   
  752.         pageName << "D:/TTS-Data/" << m_currentBook << "/" << m_currentPage;   
  753.    
  754.         string line;   
  755.         ifstream file(pageName.str().c_str());   
  756.         if(!file.is_open())     //该页为空白页    
  757.         {   
  758.             readStr << "该页为空白页";   
  759.         }   
  760.         else   
  761.         {   
  762.             ::getline(file, line);   
  763.             ::getline(file, line);   
  764.             file.close();   
  765.             readStr << "清除当前的内容, 第" << m_currentPage+1 << "页" << line   
  766.                 << "请按清除键确认清除";   
  767.         }   
  768.     }   
  769.     else    //当前状态为阅读状态    
  770.     {   
  771.         //判断该书是否有内容    
  772.         m_isLoad = true;   
  773.         if(m_bookIndex[m_currentBook].length() == 0)   
  774.         {   
  775.             STTSPlayString(m_hTTSInstance, (char*)"该书为空白", 1);   
  776.             return;   
  777.         }      
  778.         m_currentPage++;       
  779.            
  780.         //当前页的名字    
  781.         ostringstream pageName;   
  782.         pageName << "D:/TTS-Data/" << m_currentBook << "/" << m_currentPage;   
  783.         ifstream file(pageName.str().c_str());   
  784.    
  785.         if(!file.is_open()) //如果该页为空    
  786.             readStr << "第" << m_currentPage+1 << "页。本页为空白页。";   
  787.         else                //如果该页不为空    
  788.         {   
  789.             string line;   
  790.             //得到该页的第一行    
  791.             ::getline(file, line);   
  792.             ::getline(file, line);   
  793.             readStr << "第" << m_currentPage+1 << "页。" << line << "请按朗读暂停键开始阅读";   
  794.             file.close();   
  795.         }   
  796.     }   
  797.    
  798.    
  799.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  800. }   
  801.    
  802. void CTTSDlg::PrePage()   
  803. {   
  804.     ostringstream readStr;   
  805.     if(m_isSave)            //当前状态为录制状态    
  806.     {   
  807.         if(m_curSavePage == 0)   
  808.             readStr << "已到达首页";   
  809.         else   
  810.         {              
  811.             m_curSavePage--;   
  812.             readStr << "录制当前阅读的内容到第" << m_curSavePage+1 << "页"   
  813.                 << "按录制键确认录制或选择其他书页";   
  814.         }   
  815.     }   
  816.     else if(m_isDelete)     //当前状态为删除     
  817.     {   
  818.         m_isDelBook = false;   
  819.         if(m_currentPage == 0)   
  820.             readStr << "已到达首页";   
  821.         else   
  822.         {   
  823.             m_currentPage--;   
  824.             ostringstream pageName;   
  825.             pageName << "D:/TTS-Data/" << m_currentBook << "/" << m_currentPage;   
  826.    
  827.             string line;   
  828.             ifstream file(pageName.str().c_str());   
  829.             if(!file.is_open())     //该页为空白页    
  830.                 readStr << "该页为空白页";   
  831.             else   
  832.             {   
  833.                 ::getline(file, line);   
  834.                 ::getline(file, line);   
  835.                 file.close();   
  836.                 readStr << "清除当前的内容, 第" << m_currentPage+1 << "页" << line   
  837.                     << "请按清除键确认清除";   
  838.             }   
  839.         }   
  840.     }   
  841.     else    //当前状态为阅读状态    
  842.     {   
  843.         //判断该书是否有内容    
  844.         m_isLoad = true;   
  845.         if(m_bookIndex[m_currentBook].length() == 0)   
  846.         {   
  847.             STTSPlayString(m_hTTSInstance, (char*)"该书为空白", 1);   
  848.             return;   
  849.         }   
  850.            
  851.         if(m_currentPage == 0)   
  852.             readStr << "已到达首页";   
  853.         else   
  854.         {      
  855.             m_currentPage--;   
  856.             ostringstream pageName;   
  857.             pageName << "D:/TTS-Data/" << m_currentBook << "/" << m_currentPage;   
  858.             ifstream file(pageName.str().c_str());   
  859.    
  860.             if(!file.is_open())     //this page is empty    
  861.                 readStr << "第" << m_currentPage+1 << "页。本页为空白页。";   
  862.             else                    //this page is not empty    
  863.             {   
  864.                 string line;   
  865.                 //得到该页的第一行    
  866.                 ::getline(file, line);   
  867.                 ::getline(file, line);   
  868.                 readStr << "第" << m_currentPage+1 << "页。" << line << "请按朗读暂停键开始阅读";   
  869.                 file.close();   
  870.             }   
  871.         }   
  872.     }   
  873.    
  874.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  875. }   
  876.    
  877. void CTTSDlg::LoadSavedPage()   
  878. {   
  879.     ostringstream pageName;   
  880.     pageName << "D:/TTS-Data/" << m_currentBook << "/"   
  881.         << m_currentPage;   
  882.    
  883.     ifstream file(pageName.str().c_str());   
  884.    
  885.     if(!file.is_open())   
  886.     {   
  887.         STTSPlayString(m_hTTSInstance, "该页为空白页", 1);   
  888.         return;   
  889.     }   
  890.    
  891.     if(!m_page.empty())   
  892.         m_page.clear();   
  893.    
  894.     //装载存储的文件    
  895.     string line;   
  896.     while(::getline(file, line))   
  897.         m_page.push_back(line);   
  898.    
  899.     file.close();   
  900.     m_senPos = m_page.begin();   
  901.    
  902.     //更新阅读标记    
  903.     m_lastReadBook = m_currentBook;   
  904.     m_readTag[m_currentBook] = m_currentPage;   
  905. }   
  906.    
  907. void CTTSDlg::CheckSavePage()   
  908. {   
  909.     //当第二次进行确认时,保存该页内容    
  910.     if(m_isSave)   
  911.     {   
  912.         SavePage();   
  913.         return;   
  914.     }   
  915.    
  916.     m_isSave = true;   
  917.     ostringstream readStr;   
  918.     readStr << "录制当前阅读的内容到第"<< m_lastSaveBook+1 << "本书。"   
  919.         << m_bookIndex[m_lastSaveBook].c_str() << "第"    
  920.         << m_saveTag[m_lastSaveBook]+1 << "页。" << "按录制键确认录制或选择其他书页";   
  921.     m_curSavePage = m_saveTag[m_curSaveBook];   
  922.    
  923.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  924. }   
  925.    
  926. void CTTSDlg::SavePage()   
  927. {   
  928.     ostringstream dirName;   
  929.     dirName << "D:/TTS-Data/" << m_curSaveBook;   
  930.    
  931.     _finddata_t fileInfo;   
  932.     intptr_t handle;   
  933.     //如果该书还不存在,创建该书    
  934.     handle = _findfirst(dirName.str().c_str(), &fileInfo);   
  935.     if(handle == -1)   
  936.         _mkdir(dirName.str().c_str());   
  937.     _findclose(handle);   
  938.    
  939.     ostringstream pageName;   
  940.     pageName << "D:/TTS-Data/" << m_curSaveBook << "/"   
  941.             << m_curSavePage;   
  942.    
  943.     if(m_isCover)       //用户要求覆盖该页内容    
  944.     {   
  945.         ofstream file(pageName.str().c_str());   
  946.         for(list::iterator pos = m_page.begin();   
  947.             pos != m_page.end(); pos++)   
  948.             file << *pos << endl;   
  949.         file.close();   
  950.    
  951.         //更新录制标记    
  952.         m_lastSaveBook = m_curSaveBook;   
  953.         m_saveTag[m_curSaveBook] = m_curSavePage + 1;   
  954.    
  955.         //表示录制成功    
  956.         m_isCover = false;   
  957.         m_isSave = false;   
  958.    
  959.         STTSPlayString(m_hTTSInstance, "该页内容已经录制", 1);   
  960.            
  961.     }   
  962.     else   
  963.     {   
  964.         //检查该页内是否已经有内容    
  965.         ifstream checkFile(pageName.str().c_str());   
  966.         if(!checkFile.is_open())    //该页为空白页    
  967.         {   
  968.             //写入文件    
  969.             ofstream file(pageName.str().c_str());   
  970.             for(list::iterator pos = m_page.begin();   
  971.                 pos != m_page.end(); pos++)   
  972.                 file << *pos << endl;   
  973.             file.close();   
  974.    
  975.             //更新录制标记    
  976.             m_lastSaveBook = m_curSaveBook;   
  977.             m_saveTag[m_curSaveBook] = m_curSavePage + 1;   
  978.             m_isSave = false;   //录制成功    
  979.    
  980.             STTSPlayString(m_hTTSInstance, "该页内容已经录制", 1);   
  981.         }   
  982.         else        //该页已有内容    
  983.         {   
  984.             STTSPlayString(m_hTTSInstance, "本页已有内容,按录制键覆盖或选择其他页", 1);   
  985.             m_isCover = true;   
  986.         }   
  987.     }   
  988.    
  989.     //更新书目索引    
  990.     dirName << "/*.*";   
  991.     handle = _findfirst(dirName.str().c_str(), &fileInfo);   
  992.     if(handle != -1)   
  993.     {   
  994.         do   
  995.         {   
  996.             if(string(fileInfo.name) == "."   
  997.                 || string(fileInfo.name) == "..")   
  998.                 continue;   
  999.             else   
  1000.                 break;   
  1001.         }while(_findnext(handle, &fileInfo) == 0);   
  1002.     }   
  1003.     ostringstream firstPage;   
  1004.     firstPage << "D:/TTS-Data/" << m_curSaveBook << "/"   
  1005.         << fileInfo.name;   
  1006.     ifstream first(firstPage.str().c_str());   
  1007.     string line;   
  1008.     ::getline(first, line);   
  1009.     ::getline(first, line);   
  1010.     if(m_bookIndex[m_curSaveBook] != line)   
  1011.         m_bookIndex[m_curSaveBook] = line;   
  1012.        
  1013.     //if(m_curSavePage == 0)    
  1014.     //{    
  1015.     //  //这本书原本为空    
  1016.     //  list::iterator pos = m_page.begin();    
  1017.     //  pos++;    
  1018.     //  if(m_bookIndex[m_curSaveBook].length() == 0)    
  1019.     //  {    
  1020.     //      m_bookIndex[m_curSaveBook] = *pos;    
  1021.     //      m_readTag[m_curSaveBook] = 0;    
  1022.     //  }    
  1023.     //  else    
  1024.     //      m_bookIndex[m_curSaveBook] = *pos;    
  1025.     //}    
  1026. }   
  1027.    
  1028. void CTTSDlg::CheckDelete()   
  1029. {   
  1030.     if(m_isDelete)   
  1031.     {   
  1032.         Delete();   
  1033.         return;   
  1034.     }   
  1035.    
  1036.     m_isDelete = true;   
  1037.     m_currentPage = 0;   
  1038.     ostringstream readStr;   
  1039.     readStr << "清除当前整书, 第"  << m_currentBook+1 << "本书"   
  1040.         << m_bookIndex[m_currentBook] << "是否确认"    
  1041.         << "或通过前后页选择要清除的页码";   
  1042.    
  1043.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  1044. }   
  1045.    
  1046. void CTTSDlg::Delete()   
  1047. {   
  1048.     ostringstream name;   
  1049.     ostringstream readStr;   
  1050.        
  1051.     if(m_isDelBook) //清除整书    
  1052.     {   
  1053.         name << "D:/TTS-Data/" << m_currentBook << "/*.*";   
  1054.         list deleteFiles;   
  1055.    
  1056.         _finddata_t fileInfo;   
  1057.         intptr_t handle;   
  1058.    
  1059.         handle = _findfirst(name.str().c_str(), &fileInfo);   
  1060.    
  1061.         //删除该目录下所有文件    
  1062.         if(handle != -1)   
  1063.         {   
  1064.             do   
  1065.             {   
  1066.                 if(string(fileInfo.name) == "."   
  1067.                     || string(fileInfo.name) == "..")   
  1068.                     continue;   
  1069.                 ostringstream filename;   
  1070.                 filename << "D:/TTS-Data/" << m_currentBook   
  1071.                     << "/" << fileInfo.name;   
  1072.                 //int res = remove(fileInfo.name);    
  1073.                 deleteFiles.push_back(filename.str());   
  1074.             }while(_findnext(handle, &fileInfo) == 0);   
  1075.         }   
  1076.         _findclose(handle);   
  1077.    
  1078.         for(list::iterator pos = deleteFiles.begin();   
  1079.             pos != deleteFiles.end(); pos++)   
  1080.             int res = remove(pos->c_str());   
  1081.         ostringstream dirName;   
  1082.         dirName << "D:/TTS-Data/" << m_currentBook;   
  1083.         int res = _rmdir(dirName.str().c_str());   
  1084.         //更新书目索引    
  1085.         m_bookIndex[m_currentBook] = "";   
  1086.         m_readTag[m_currentBook] = 0;   
  1087.         m_saveTag[m_currentBook] = 0;   
  1088.         m_isDelete = false;   
  1089.    
  1090.         readStr << "第" << m_currentBook+1 << "本书已经清除";   
  1091.     }   
  1092.     else        //清除一页    
  1093.     {   
  1094.         name << "D:/TTS-Data/" << m_currentBook << "/"   
  1095.             << m_currentPage;   
  1096.    
  1097.         ifstream checkFile(name.str().c_str());   
  1098.         if(!checkFile.is_open())    //该页为空白页    
  1099.             return;   
  1100.         else   
  1101.             checkFile.close();   
  1102.            
  1103.         int res = remove(name.str().c_str());   
  1104.         m_isDelete = false;   
  1105.         readStr << "第" << m_currentBook + 1 << "本书第" << m_currentPage+1 << "页已经清除";   
  1106.    
  1107.         //更新书目    
  1108.         _finddata_t fileInfo;   
  1109.         intptr_t handle;   
  1110.         ostringstream dirName;   
  1111.         dirName << "D:/TTS-Data/" << m_currentBook << "/*.*";   
  1112.         handle = _findfirst(dirName.str().c_str(), &fileInfo);   
  1113.         if(handle != -1)   
  1114.         {   
  1115.             do   
  1116.             {   
  1117.                 if(string(fileInfo.name) == "."   
  1118.                     || string(fileInfo.name) == "..")   
  1119.                     continue;   
  1120.                 else   
  1121.                     break;   
  1122.             }while(_findnext(handle, &fileInfo) == 0);   
  1123.         }   
  1124.         _findclose(handle);   
  1125.    
  1126.         ostringstream firstPage;   
  1127.         firstPage << "D:/TTS-Data/" << m_curSaveBook << "/"   
  1128.             << fileInfo.name;   
  1129.         ifstream first(firstPage.str().c_str());   
  1130.         string line;   
  1131.         ::getline(first, line);   
  1132.         ::getline(first, line);   
  1133.         if(m_bookIndex[m_curSaveBook] != line)   
  1134.             m_bookIndex[m_curSaveBook] = line;   
  1135.         first.close();   
  1136.    
  1137.         if(line == "")   
  1138.         {   
  1139.             m_readTag[m_currentBook] = 0;   
  1140.             m_saveTag[m_currentBook] = 0;   
  1141.             ostringstream delDir;   
  1142.             delDir << "D:/TTS-Data/" << m_currentBook;   
  1143.             remove(delDir.str().c_str());   
  1144.         }   
  1145.    
  1146.    
  1147.     }   
  1148.    
  1149.     STTSPlayString(m_hTTSInstance, (char*)readStr.str().c_str(), 1);   
  1150. }   
  1151.    
  1152. void CTTSDlg::SaveIndex()   
  1153. {   
  1154.     ofstream file("D:/TTS-Data/index.dat");   
  1155.    
  1156.     file << m_lastReadBook << " " << m_lastSaveBook << endl;   
  1157.     for(unsigned i = 0; i < m_bookIndex.size(); i++)   
  1158.     {   
  1159.         file << m_readTag[i] << " "   
  1160.             << m_saveTag[i] << " "   
  1161.             << m_bookIndex[i] << endl;   
  1162.     }   
  1163.     file.close();   
  1164. }