I am using MS Speech API 5.1 with mingw compiler. I don't have VS hence but I was able to compile the code with c::b.
The code snippet is below:
#include <sapi.h>
int main(int argc, char* argv[])
{
ISpVoice * pVoice = NULL;
if (FAILED(::CoInitialize(NULL)))
return FALSE;
HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
if( SUCCEEDED( hr ) )
{
hr = pVoice->Speak(L"Hello world", 0, NULL);
pVoice->Release();
pVoice = NULL;
}
::CoUninitialize();
return TRUE;
}
When I execute I found
hr = pVoice->Speak(L"Hello world", 0, NULL);
returning NULL. After looking around for a while, I ran the example TTSApp.exe from the MS SAPI folder. By default the voice was selected as "Microsoft Marry". When I type a text and click Start, no speech sound is produce and I got "Speak error". When I changed the voice to "Microsoft Anna - English (United States)", it worked.
I do not know if I am thinking correct, but is the code of mine also failing because of a wrong/default voice selection ("Microsoft Marry")? Is there any way I can change the voice to "Microsoft Anna - English (United States)" for testing?
I need you help here. Can you help me get the SAPI working fro the above code?
Thanks!
Since this is a microsoft specific question.
I use some vb mixed within some system() calls it results in much simpler code.
I haven't cleaned it up, but it works well
int say(std::string s)
{
string part1content;
string part2content;
string word,complete;
const char * temp2="WScript.exe Scrpt.vbs";
const char * temp="Scrpt.vbs";
string pat1=(
"\'By Timbo\n\n\
Const SVSFlagsAsync = 1\n\
const SVSFPurgeBeforeSpeak =2\n\n\
Dim Speech\n\
Dim FSO\n\n\
CreateObjects\n\
Main\n\
DestroyObjects\n\
Quit\n\n\
Sub Main\n\
Dim sText\n\n\
sText = (\""
);
string pat2=
(
"\")\n\
Speech.rate = 0.05\n\
If sText <> \"\" Then\n\
SpeakText sText\n\n\
End If\n\
End Sub\n\n\
Sub SpeakText(sText)\n\
On Error Resume Next\n\
Speech.Speak sText, SVSFlagsAsync + SVSFPurgeBeforeSpeak\n\
Do\n\
Sleep 200\n\
Loop Until Speech.WaitUntilDone(10)\n\
End Sub\n\n\
Sub StopSpeaking()\n\
On Error Resume Next\n\
Speech.Speak vbNullString, SVSFPurgeBeforeSpeak\n\
Set Speech = Nothing\n\
End Sub\n\n\
Sub CreateObjects\n\
Set Speech = CreateObject(\"SAPI.SpVoice\")\n\
Set FSO = CreateObject(\"Scripting.FileSystemObject\")\n\
End Sub\n\n\
Sub DestroyObjects\n\
Set Speech = Nothing\n\
Set FSO = Nothing\n\
End Sub\n\n\
Sub Sleep(nTimeout)\n\
WScript.Sleep nTimeout\n\
End Sub\n\n\
Sub Quit\n\
WScript.Quit\n\
End Sub\n\n\
"
);
/*Will say string s*/
complete=pat1+s+pat2;
ofstream myfile;
myfile.open (temp);
myfile << complete;
myfile.close();
system(temp2);
complete.clear();
s.clear();
}
For different voice Change pat2 with
string pat2=
(
"\")\n\
Speech.rate = 0.05\n\
If sText <> \"\" Then\n\
SpeakText sText\n\n\
End If\n\
End Sub\n\n\
Sub SpeakText(sText)\n\
On Error Resume Next\n\
Speech.Speak sText, SVSFlagsAsync + SVSFPurgeBeforeSpeak\n\
Do\n\
Sleep 200\n\
Loop Until Speech.WaitUntilDone(10)\n\
End Sub\n\n\
Sub StopSpeaking()\n\
On Error Resume Next\n\
Speech.Speak vbNullString, SVSFPurgeBeforeSpeak\n\
Set Speech = Nothing\n\
End Sub\n\n\
Sub CreateObjects\n\
Set Speech = CreateObject(\"SAPI.SpVoice\")\n\
with Speech \n\
Set .voice = .getvoices.item(1)\n\
.Volume = 100\n\
.Rate = 4\n\
end with\n\
Set FSO = CreateObject(\"Scripting.FileSystemObject\")\n\
End Sub\n\n\
Sub DestroyObjects\n\
Set Speech = Nothing\n\
Set FSO = Nothing\n\
End Sub\n\n\
Sub Sleep(nTimeout)\n\
WScript.Sleep nTimeout\n\
End Sub\n\n\
Sub Quit\n\
WScript.Quit\n\
End Sub\n\n\
"
);
Then you can just use it simply by calling say("This is a test");
For more control you can use pipes instead of sytem() , this will enable you to kill the vbscript process if you want to stop it.