Microsoft Text-To-Speech不会说重音字符

时间:2019-03-20 14:59:05

标签: c++ text-to-speech sapi

我正在使用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带有重音字符。但是,我创建了一个名为wstring的{​​{1}}变量,在这里我的字符串被转换,这里带重音的字符被替换为一个空的正方形。然后,创建一个LPCWSTR变量(指向宽字符串的长指针)以说出输入的文本。下面是我的变量值的图片。

Variable values

也许我的代码有问题,但是我该怎么做才能确保说出重音字符呢?

2 个答案:

答案 0 :(得分:2)

您不能简单地将单字节或多字节字符串(charstd::string)复制到宽字符串(wchar_tstd::wstring) 。您需要在编码或字符集之间进行正确的转换。

您必须确定用于两个字符串的正确编码。在Windows上,std::string数据通常采用本地编码,例如Windows-1252,而std::wstring数据则采用UTF-16。

在Windows上,您可以使用MultiByteToWideChar进行转换。

或者,您可以使用标准功能,例如mbstowcsstd::mbtowc

答案 1 :(得分:0)

我实现了@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