Search code examples
c++text-to-speechsapispeech-synthesis

Is there a possibility to ignore words in Microsoft Text To Speech using SAPI?


I'm developing a Text-To-Speech application using Microsoft SAPI. The ISpVoice::Speak works great, however some special characters are spoken aloud and shouldn't be. These spoken characters are (/, * _)

I have found out that it is possible to create rules, but only using Speech Recognition (source). I wonder if it is possible to implement it in Text-To-Speech. Here is some code if it helps.

int ttsSpeak( const char* text ) //Text to Speech speaking function
{
   if( SUCCEEDED(hr) )
   {
      hr = SpEnumTokens( SPCAT_VOICES, NULL, NULL, &cpEnum );

      cpEnum->Item( saveVoice, &cpVoiceToken ); //get saveVoice token defined at line 136
      cpVoice->SetVoice( cpVoiceToken ); //Initialization of the voice

      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 );

      //skip characters ( /, *, _ )

      printf( "Text To Speech processing\n" );
      hr = cpVoice->Speak( wstr, SPF_DEFAULT, NULL );

      saveText = text;

      cpEnum.Release();
      cpVoiceToken.Release();
      delete new wchar_t[ wchars_num ];
   }
   else
   {
      printf( "Could not speak entered text\n" );
   }

   return true;
}

Is it possible to skip characters being spoken aloud? For example, I create an XML file where I can define what the engine can say, and cannot.


Solution

  • I managed to solve my issue thanks to Eric's comment. If you modifiy the text before the engine speaks it, you can remove the characters you want. Here is the code which allows to preprocess the text

      string strText( text ); //transform the const char* text into string
      string specialChars = "/*_"; //define the characters you want to skip
      string::iterator it; //declare iterator
      for( it = strText.begin(); it < strText.end(); it++ ) //loop through the sentence
      {
         bool found = specialChars.find( *it ) != string::npos;
         if( found )
         {
            *it = ' ';
         }
      }