LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Text-Speech in CVI using SAPI as ActiveX Automation Server

I am creating a voice alarming system.  I have the tools and hardware to place phone calls to chosen users, and deliver a voice message.  The msg format is typically .WAV files.  All of this system is up and running and doing beautifully.

However, I would like to create custom messages, which requires a text -> speech processor to create the necessary WAV file (from text) to deliver via phone.

I have used the ActiveX Automation Server (Tools:Create ActiveX Automation Server) to create a function panel from the Microsoft SAPI engine.  However, I am stumped at this point.  No idea where to start.  All in want is a simple text-speech-file routine.  All the other tools are up and running.

Any examples, help, tips, etc would be appreciated.  I am up against a deadline of June 23rd to demo for a group.

Thanks in advance, David Eaton
David Eaton
0 Kudos
Message 1 of 8
(5,060 Views)

Hi David,

The following code converts text to speech using SAPI.

const char * text = "hello world";
CAObjHandle  voice = 0;
long streamNumber;

Speech_NewISpeechVoice(NULL, 0, LOCALE_NEUTRAL, 0, &voice);
Speech_ISpeechVoiceSpeak(voice, NULL, text, SpeechConst_SVSFDefault, &streamNumber);
CA_DiscardObjHandle(voice);

For more info on the Automation interface to the SAPI SDK, see:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/SAPI51sr/html/VB_SpVoice_Interface....

0 Kudos
Message 2 of 8
(5,049 Views)
David,

The following code can be used as a template for your requirement

Jan Dahle


#include <windows.h>
#include <sapi.h>

void SpeakAlarmMessage(char *msg, int msgLen, int volume)
{
//Speak the given text

static ISpVoice *pVoice = NULL;
GUID CLSID_SpVoice = {0x96749377, 0x3391, 0x11D2, 0x9E, 0xE3, 0x0, 0xC0,
0x4F, 0x79, 0x73, 0x96};
GUID IID_ISpVoice = {0x6C44DF74, 0x72B9, 0x4992, 0xA1, 0xEC, 0xEF, 0x99,
0x6E, 0x04, 0x22, 0xD4};

WCHAR *wText;
char headerTxt[]= "<emph> GENERAL ALARM!. GENERAL ALARM!. <rate
speed='2'><pitch absmiddle='-3'><silence msec='1000'/>";
char tailTxt[]= "!<silence msec='1000'/> General ALARM!";
int i,j=0;


// Speech is using COM technology.Only continue if COM is successfully
initialized
if (SUCCEEDED(CoInitialize(NULL)))
{
// Create a speech instance
// if(SUCCEEDED(CoCreateInstance(&CLSID_SpVoice, NULL, CLSCTX_ALL,
&IID_ISpVoice, (VOID**)&pVoice)))
//if(SUCCEEDED(CoCreateInstance(&CLSID_SpVoice, NULL,
CLSCTX_INPROC_SERVER, &IID_ISpVoice, (VOID**)&pVoice)))
if ( pVoice ==NULL)
CoCreateInstance(&CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER,
&IID_ISpVoice, (VOID**)&pVoice);

if ( pVoice !=NULL)
{
// CVI 5.5 does not support WCHAR. Do it manually. Get some memory and
copy the text into it
if(wText = calloc (sizeof(headerTxt)+msgLen+sizeof(tailTxt),
sizeof(WCHAR)))
{
for (i=0; i< sizeof(headerTxt)-1;i++, j++) wText[j] = headerTxt[i];
for (i=0; i< msgLen ;i++, j++) wText[j] = msg[i];
//for (i=0; i< sizeof(tailTxt)-1 ;i++, j++) wText[j] = tailTxt[i];
wText[j] ='\0';

// Set the volume and speak
pVoice->lpVtbl->SetVolume (pVoice, (USHORT) volume);
pVoice->lpVtbl->Speak(pVoice, wText , SPF_IS_XML | SPF_ASYNC , NULL);

free(wText);
}
//Release the speech resource.
pVoice->lpVtbl->Release(pVoice);
}

// Release used COM resources.
CoUninitialize(); // #NOTE
}
}

"FoodScience" <x@no.email> wrote in message
news:1179864617182-524925@exchange.ni.com...
>I am creating a voice alarming system.&nbsp; I have the tools and hardware
>to place phone calls to chosen users, and deliver a voice message.&nbsp;
>The msg format is typically .WAV files.&nbsp; All of this system is up and
>running and doing beautifully.However, I would like to create custom
>messages, which requires a text -&gt; speech processor to create the
>necessary WAV file (from text) to deliver via phone.I have used the ActiveX
>Automation Server (Tools:Create ActiveX Automation Server) to create a
>function panel from the Microsoft SAPI engine.&nbsp; However, I am stumped
>at this point.&nbsp; No idea where to start.&nbsp; All in want is a simple
>text-speech-file routine.&nbsp; All the other tools are up and running.Any
>examples, help, tips, etc would be appreciated.&nbsp; I am up against a
>deadline of June 23rd to demo for a group.Thanks in advance, David Eaton


0 Kudos
Message 3 of 8
(5,042 Views)
Thanks for the info.  I am traveling, but will give the code a try when I get back to the office.

Regards, Dave



David Eaton
0 Kudos
Message 4 of 8
(5,040 Views)
Mohan,

The code worked perfectly.  I was able to send a voice msg to the speakers.  Nice quality.

Two other questions:

1) How do I route the output to a file, such as WAV format?  This is the format preferred by the voice server card.
2) How do I change or use different voices.  I have an AT&T licenses for the Natural Voices, and the quality is much better than the MS voice.

I will experiment of this end.

Sorry to be a bother, but short of time.

Thanks in advance, David

David Eaton
0 Kudos
Message 5 of 8
(4,978 Views)
David,

For the first question there is a small example of using SAPI to save to WAV file here. I'm not sure about the second one but using this method might be the right function.
Test Engineer - CTA
0 Kudos
Message 6 of 8
(4,954 Views)
Jon,

Thanks for the info.  I will take a look at the code.

I found yesterday that I can control the default voice in Control Panel under Speech.  I only use one voice, and that will be a easy way to set the default.  Once I have a better grasp of the SAPI functions, I can do it that way.

I tried a simple routine to get the available voices. 

void GetVoices(void)
{
/* This returns a list of voices */

CAObjHandle vtest = 0;                                    
SpeechObj_ISpeechObjectToken  voices_avail;


    vstat = Speech_NewISpeechVoice (NULL, &vtest);                                  // create a new voice
    if (vstat >= 0)
    {
        vstat = Speech_ISpeechVoiceGetVoices (vtest, NULL, "", "", &voices_avail);        // get the available voices
        if (vstat >= 0)
        {
            vstat = Speech_GetProperty (vtest, NULL, Speech_ISpeechVoiceVoice, CAVT_CSTRING, voice_name);
        }       
    }
    CA_DiscardObjHandle(vtest);
}

The VoiceGetVoices command returns correctly (no errors), but voices_avail is just a 4 byte value.  How do I extract the voice information at that point.  I tried Speech_GetProperty, but it returns an error.

Any help would be appreciated.



David Eaton
0 Kudos
Message 7 of 8
(4,951 Views)
David,

I would recommend consulting the MSDN documentation for the GetVoices() method as well as the example code for usage of the function. If that fails you could try googling it or searching on MSDN forums as NI does not support the SAPI due to it being a Microsoft product.
Test Engineer - CTA
0 Kudos
Message 8 of 8
(4,928 Views)