Microsoft Text-To-Speech 不会说重音字符
Microsoft Text-To-Speech doesn't speak accented characters
我正在使用 Microsoft sapi
库开发文本转语音应用程序。我实现了朗读功能,发现重音字符 (à,á,â,ä,é,è,ê,í,ì,î,ó,ò,ô,ö,ù,ú,û ,ü) 没有说话。
这是我的代码:
int ttsSpeak( const char* text ) //Text to Speech speaking function
{
if( SUCCEEDED(hr) )
{
hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );
cpEnum->Item( saveVoice, &cpVoiceToken );
cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice
string str( text );
cout << str;
std::wstring stemp = std::wstring( str.begin(), str.end() );
LPCWSTR sw = ( LPCWSTR )stemp.c_str(); //variable allowing to speak my entered text
printf( "Text To Speech processing\n" );
hr = cpVoice->Speak( sw, SPF_DEFAULT, NULL ); //speak my text
saveText = text;
cpEnum.Release();
cpVoiceToken.Release();
}
else
{
printf( "Could not speak entered text\n" );
}
return true;
}
我调试了我的应用程序,发现变量 str
获取重音字符。但是,我创建了一个名为 stemp
的 wstring
变量,其中我的字符串被转换,这里重音字符被替换为一个空方块。然后,创建一个 LPCWSTR 变量(指向常量宽字符串的长指针)以读出输入的文本。下面是我的变量值的图片。
也许我的代码有问题,但我该怎么做才能确保重音字符被说出来?
不能简单地将单字节或多字节字符串(char
、std::string
)复制到宽字符串(wchar_t
、std::wstring
).您需要在编码或字符集之间进行适当的转换。
您必须确定用于两个字符串的正确编码。在 Windows 上,std::string
数据通常采用本地编码,例如 Windows-1252 和 std::wstring
数据采用 UTF-16。
在 Windows 上,您可以使用 MultiByteToWideChar 进行转换。
或者,您可以使用标准函数,例如 mbstowcs
或 std::mbtowc
。
我实施了@rveerd 建议的 MultiByteToWideChar
。这是代码:
int ttsSpeak( const char* text ) //Text to Speech speaking function
{
if( SUCCEEDED(hr) )
{
hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );
cpEnum->Item( saveVoice, &cpVoiceToken );
cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice
//processing conversion
int wchars_num = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
wchar_t* wstr = new wchar_t[ wchars_num ];
MultiByteToWideChar( CP_ACP, 0, text, -1, wstr, wchars_num );
printf( "Text To Speech processing\n" );
hr = cpVoice->Speak( wstr, SPF_DEFAULT, NULL ); //speak my text
saveText = text;
cpEnum.Release();
cpVoiceToken.Release();
delete new wchar_t[wchars_num];
}
else
{
printf( "Could not speak entered text\n" );
}
return true;
}
我还找到了一种更短的转换方法。只需将 MultiByteToWideChar
代码替换为以下代码:
CA2W pszWide( str.c_str(), CP_ACP);
hr = cpVoice->Speak( pszWide, SPF_DEFAULT, NULL );
编辑:我替换了CP_UTF7,因为它很少被使用。 CP_UTF8 是首选。但是,它对我不起作用,但我发现 CP_ACP 对我有用。有关详细信息,请查看 link @rveerd 发布的
我正在使用 Microsoft sapi
库开发文本转语音应用程序。我实现了朗读功能,发现重音字符 (à,á,â,ä,é,è,ê,í,ì,î,ó,ò,ô,ö,ù,ú,û ,ü) 没有说话。
这是我的代码:
int ttsSpeak( const char* text ) //Text to Speech speaking function
{
if( SUCCEEDED(hr) )
{
hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );
cpEnum->Item( saveVoice, &cpVoiceToken );
cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice
string str( text );
cout << str;
std::wstring stemp = std::wstring( str.begin(), str.end() );
LPCWSTR sw = ( LPCWSTR )stemp.c_str(); //variable allowing to speak my entered text
printf( "Text To Speech processing\n" );
hr = cpVoice->Speak( sw, SPF_DEFAULT, NULL ); //speak my text
saveText = text;
cpEnum.Release();
cpVoiceToken.Release();
}
else
{
printf( "Could not speak entered text\n" );
}
return true;
}
我调试了我的应用程序,发现变量 str
获取重音字符。但是,我创建了一个名为 stemp
的 wstring
变量,其中我的字符串被转换,这里重音字符被替换为一个空方块。然后,创建一个 LPCWSTR 变量(指向常量宽字符串的长指针)以读出输入的文本。下面是我的变量值的图片。
也许我的代码有问题,但我该怎么做才能确保重音字符被说出来?
不能简单地将单字节或多字节字符串(char
、std::string
)复制到宽字符串(wchar_t
、std::wstring
).您需要在编码或字符集之间进行适当的转换。
您必须确定用于两个字符串的正确编码。在 Windows 上,std::string
数据通常采用本地编码,例如 Windows-1252 和 std::wstring
数据采用 UTF-16。
在 Windows 上,您可以使用 MultiByteToWideChar 进行转换。
或者,您可以使用标准函数,例如 mbstowcs
或 std::mbtowc
。
我实施了@rveerd 建议的 MultiByteToWideChar
。这是代码:
int ttsSpeak( const char* text ) //Text to Speech speaking function
{
if( SUCCEEDED(hr) )
{
hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );
cpEnum->Item( saveVoice, &cpVoiceToken );
cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice
//processing conversion
int wchars_num = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
wchar_t* wstr = new wchar_t[ wchars_num ];
MultiByteToWideChar( CP_ACP, 0, text, -1, wstr, wchars_num );
printf( "Text To Speech processing\n" );
hr = cpVoice->Speak( wstr, SPF_DEFAULT, NULL ); //speak my text
saveText = text;
cpEnum.Release();
cpVoiceToken.Release();
delete new wchar_t[wchars_num];
}
else
{
printf( "Could not speak entered text\n" );
}
return true;
}
我还找到了一种更短的转换方法。只需将 MultiByteToWideChar
代码替换为以下代码:
CA2W pszWide( str.c_str(), CP_ACP);
hr = cpVoice->Speak( pszWide, SPF_DEFAULT, NULL );
编辑:我替换了CP_UTF7,因为它很少被使用。 CP_UTF8 是首选。但是,它对我不起作用,但我发现 CP_ACP 对我有用。有关详细信息,请查看 link @rveerd 发布的