char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );
delete [/url] p;
CString newText;
char *p2="";
int i=0;
while(1){
if(p=='。')
break;
else if(p=='\0')
break;
p2 = p[i++];
}
文章「。」で止まってくれません!!!!!!!!!
エラー
音声合成の改良
すいません。
このプログラムは、音声合成ができるものです。そこで元のプログラムを改良して、文字を読み上げる際に「。」という文字が来たら次の文字を読む前に一時停止するというものを作りたいのですが、なかなかエラーで作れません。どうしたらよいのでしょうか?
プログラム
#include "stdafx.h"
#include "SampleSpeech.h"
#include "SampleSpeechDlg.h"
#include <sapi.h>
#include<stdio.h>
#include <time.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[/url] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// アプリケーションのバージョン情報で使われている CAboutDlg ダイアログ
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// ダイアログ データ
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard は仮想関数のオーバーライドを生成します
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV のサポート
//}}AFX_VIRTUAL
// インプリメンテーション
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// メッセージ ハンドラがありません。
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSampleSpeechDlg ダイアログ
CSampleSpeechDlg::CSampleSpeechDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSampleSpeechDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSampleSpeechDlg)
m_sText = _T("");
//}}AFX_DATA_INIT
// メモ: LoadIcon は Win32 の DestroyIcon のサブシーケンスを要求しません。
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSampleSpeechDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSampleSpeechDlg)
DDX_Text(pDX, IDC_EDIT1, m_sText);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSampleSpeechDlg, CDialog)
//{{AFX_MSG_MAP(CSampleSpeechDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSampleSpeechDlg メッセージ ハンドラ
BOOL CSampleSpeechDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// "バージョン情報..." メニュー項目をシステム メニューへ追加します。
// IDM_ABOUTBOX はコマンド メニューの範囲でなければなりません。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
// ウィンドウがダイアログでない時は自動的に設定しません。
SetIcon(m_hIcon, TRUE); // 大きいアイコンを設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンを設定
// TODO: 特別な初期化を行う時はこの場所に追加してください。
return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}
void CSampleSpeechDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CSampleSpeechDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
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;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CSampleSpeechDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSampleSpeechDlg::OnButton1()
{
UpdateData();
ISpVoice* pVoice = NULL;
if (FAILED(CoInitialize(NULL)))
{
AfxMessageBox("Error to intiliaze COM");
return;
}
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if( SUCCEEDED( hr ) )
{
/*ここが変更した場所*/
char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );
delete [/url] p;
CString newText;
char *p2 = new char[m_sText.GetLength()+1];
strcpy( p2, "" );
delete [/url] p2;
int i = 0;
while(1){
if(*p=='。')
break;
else if(*p=='\0')
break;
*p2++ = *p++;
}
newText = p2;
hr = pVoice->Speak(newText.AllocSysString(), SPF_DEFAULT, NULL);
pVoice->Release();
pVoice = NULL;
}
CoUninitialize();
}
void CSampleSpeechDlg::OnButton2()
{ AfxGetMainWnd()->PostMessage(WM_CLOSE);
}
このプログラムは、音声合成ができるものです。そこで元のプログラムを改良して、文字を読み上げる際に「。」という文字が来たら次の文字を読む前に一時停止するというものを作りたいのですが、なかなかエラーで作れません。どうしたらよいのでしょうか?
プログラム
#include "stdafx.h"
#include "SampleSpeech.h"
#include "SampleSpeechDlg.h"
#include <sapi.h>
#include<stdio.h>
#include <time.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[/url] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// アプリケーションのバージョン情報で使われている CAboutDlg ダイアログ
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// ダイアログ データ
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard は仮想関数のオーバーライドを生成します
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV のサポート
//}}AFX_VIRTUAL
// インプリメンテーション
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// メッセージ ハンドラがありません。
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSampleSpeechDlg ダイアログ
CSampleSpeechDlg::CSampleSpeechDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSampleSpeechDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSampleSpeechDlg)
m_sText = _T("");
//}}AFX_DATA_INIT
// メモ: LoadIcon は Win32 の DestroyIcon のサブシーケンスを要求しません。
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSampleSpeechDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSampleSpeechDlg)
DDX_Text(pDX, IDC_EDIT1, m_sText);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSampleSpeechDlg, CDialog)
//{{AFX_MSG_MAP(CSampleSpeechDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSampleSpeechDlg メッセージ ハンドラ
BOOL CSampleSpeechDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// "バージョン情報..." メニュー項目をシステム メニューへ追加します。
// IDM_ABOUTBOX はコマンド メニューの範囲でなければなりません。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
// ウィンドウがダイアログでない時は自動的に設定しません。
SetIcon(m_hIcon, TRUE); // 大きいアイコンを設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンを設定
// TODO: 特別な初期化を行う時はこの場所に追加してください。
return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}
void CSampleSpeechDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CSampleSpeechDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
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;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CSampleSpeechDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CSampleSpeechDlg::OnButton1()
{
UpdateData();
ISpVoice* pVoice = NULL;
if (FAILED(CoInitialize(NULL)))
{
AfxMessageBox("Error to intiliaze COM");
return;
}
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if( SUCCEEDED( hr ) )
{
/*ここが変更した場所*/
char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );
delete [/url] p;
CString newText;
char *p2 = new char[m_sText.GetLength()+1];
strcpy( p2, "" );
delete [/url] p2;
int i = 0;
while(1){
if(*p=='。')
break;
else if(*p=='\0')
break;
*p2++ = *p++;
}
newText = p2;
hr = pVoice->Speak(newText.AllocSysString(), SPF_DEFAULT, NULL);
pVoice->Release();
pVoice = NULL;
}
CoUninitialize();
}
void CSampleSpeechDlg::OnButton2()
{ AfxGetMainWnd()->PostMessage(WM_CLOSE);
}
Re:音声合成の改良
ソースを掲示する場合は規約に従いpreタグを使用してください。
変更した場所についてざっと見ましたがC++をよく理解されいないご様子。
元がどうだったのかわかりませんがnewして確保し領域を即座にdeleteで解放していたり
していて、「。」の判定以外にもおかしなところだらけです。
質問者さんはC++についてどの程度習得されていますか?
変更した場所についてざっと見ましたがC++をよく理解されいないご様子。
元がどうだったのかわかりませんがnewして確保し領域を即座にdeleteで解放していたり
していて、「。」の判定以外にもおかしなところだらけです。
質問者さんはC++についてどの程度習得されていますか?
Re:音声合成の改良
全くの初心者です。。
char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );
delete [/url] p;
の部分はCCString型からchar型へ変更するためのプログラムを参考にしました。
char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );
delete [/url] p;
の部分はCCString型からchar型へ変更するためのプログラムを参考にしました。
Re:音声合成の改良
参考にしたのはここですかね?
http://rararahp.cool.ne.jp/vc/vctips/cstringchar.htm
参考にするのはいいんですけど理解していないと意味がないですね。
いろいろな例を理解せず流用してくっつけただけでは正しいプログラムはできません。
例えば
delete [/url] p;
とした段階でnewで確保したメモリは解放されているためアクセスしてはいけません。
pに確保した領域を使用するのはdeleteよりも前です。
まず、これだけでも修正できますか?
http://rararahp.cool.ne.jp/vc/vctips/cstringchar.htm
参考にするのはいいんですけど理解していないと意味がないですね。
いろいろな例を理解せず流用してくっつけただけでは正しいプログラムはできません。
例えば
delete [/url] p;
とした段階でnewで確保したメモリは解放されているためアクセスしてはいけません。
pに確保した領域を使用するのはdeleteよりも前です。
まず、これだけでも修正できますか?