Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: Jim on January 09, 2007

Title: speech in freebasic
Post by: Jim on January 09, 2007
Here it is then, made all the more difficult by the fact the Speech API (SAPI) isn't present in FreeBasic - I had to do it myself...

Save this one as sapi.bi
NB. This file implements just enough to speak and change the pitch and volume of the voice.  I've left loads of it stubbed.
Code: [Select]
dim IID_ISpVoice as GUID    => ( &H6c44df74, &H72b9, &H4992, {&Ha1, &Hec, &Hef, &H99, &H6e, &H04, &H22, &Hd4 })
dim CLSID_SpVoice as GUID  => ( &H96749377, &H3391, &H11d2, {&H9e, &He3, &H00, &Hc0, &H4f, &H79, &H73, &H96 })

type ISpVoiceVtbl_ as ISpVoiceVtbl

type ISpVoice
lpVtbl as ISpVoiceVtbl_ ptr
end type

#define SPF_DEFAULT 0

type ISpVoiceVtbl
rem iunknown
QueryInterface as function(byval as ISpVoice ptr, byval as IID ptr, byval as any ptr) as HRESULT
AddRef as function(byval as ISpVoice ptr) as ULONG
Release as function(byval as ISpVoice ptr) as ULONG

rem stubs
SetNotifySink as function() as HRESULT
SetNotifyWindowMessage as function() as HRESULT
SetNotifyCallbackFunction as function() as HRESULT
SetNotifyCallbackInterface as function() as HRESULT
SetNotifyWin32Event as function() as HRESULT
WaitForNotifyEvent as function() as HRESULT
GetNotifyEventHandle as function() as HRESULT
SetInterest as function() as HRESULT
GetEvents as function() as HRESULT   
GetInfo as function() as HRESULT
SetOutput as function() as HRESULT
GetOutputObjectToken as function() as HRESULT
GetOutputStream as function() as HRESULT

rem done
Pause as function(byval as ISpVoice ptr) as HRESULT
Resume as function(byval as ISpVoice ptr) as HRESULT

rem stubs
SetVoice as function() as HRESULT
GetVoice as function() as HRESULT

        rem done
Speak as function(byval as ISpVoice ptr, byval pwcs as wstring ptr, byval dwFlags as DWORD, byval pulStreamNumber as ULONG ptr) as HRESULT

rem stubs
SpeakStream as function() as HRESULT
GetStatus as function() as HRESULT
Skip as function() as HRESULT
SetPriority as function() as HRESULT
GetPriority as function() as HRESULT
SetAlertBoundary as function() as HRESULT
GetAlertBoundary as function() as HRESULT

rem done       
        SetRate as function(byval as ISpVoice ptr, byval RateAdjust as integer) as HRESULT
        GetRate as function(byval as ISpVoice ptr, byval RateAdjust as integer ptr) as HRESULT
        SetVolume as function(byval as ISpVoice ptr, byval usVolume as ushort) as HRESULT
        GetVolume as function(byval as ISpVoice ptr, byval pusVolume as ushort ptr) as HRESULT
WaitUntilDone as function(byval as ISpVoice ptr, byval msTimeout as ULONG) as HRESULT       

rem stubs
SetSyncSpeakTimeout as function() as HRESULT
GetSyncSpeakTimeout as function() as HRESULT
SpeakCompleteEvent as function() as HRESULT
IsUISupported as function() as HRESULT
DisplayUI as function() as HRESULT
end type

Save this one as speech.bas
Code: [Select]
option explicit

#include once "windows.bi"
#include once "win/winnt.bi"
#include once "win/objbase.bi"
#include once "sapi.bi"
#inclib "ole32"

dim voice as ISpVoice ptr

dim text as wstring * 14 => "Hello, World"

CoInitialize(NULL)

CoCreateInstance(@CLSID_SpVoice, NULL, CLSCTX_ALL, @IID_ISpVoice, cast (any ptr, @voice))

voice->lpVtbl->Speak(voice, text, SPF_DEFAULT, NULL)
voice->lpVtbl->WaitUntilDone(voice, INFINITE)

voice->lpVtbl->Release(voice)

CoUninitialize()

Save both files into the same folder.

Jim
Title: Re: speech in freebasic
Post by: Dr_D on January 09, 2007
That's awesome work man. I think I was trying to post at the same time you were editing your last post in the other thread. Anyway, did you know about Swig? It's an utility to help in translating headers to FB.
Title: Re: speech in freebasic
Post by: rdc on January 09, 2007
Very cool, Jim.
Title: Re: speech in freebasic
Post by: Jim on January 09, 2007
I didn't know about it, but I'll definitely use it next time since it's a total pain doing it by hand.  Karma+!

Jim
Title: Re: speech in freebasic
Post by: Dr_D on January 09, 2007
I know I'm childish... I just feel the need to put it in a loop saying, "Shut the !@#$ up, newb!"  :2funny: :2funny: :2funny:

EDIT... Where did you find documentation for this? The MSDN is chocked full of gobbledy gook! I was wondering if there are functions to change the pitch & stuff also? Maybe a way t query which part of the sentence is being spoken at the time? That would make it easy to sync with a talking head, ya know? ;)
Title: Re: speech in freebasic
Post by: Jim on January 09, 2007
Code: [Select]
voice->lpVtbl->SetRate(voice, speed)

speed is between -10 (fast) and 10 (slow).
Volume's something similar.

It's all in MSDN.  I was looking at the SAPI reference
http://msdn2.microsoft.com/en-us/library/ms719576.aspx (http://msdn2.microsoft.com/en-us/library/ms719576.aspx)

I have all the headers and help in with Visual Studio which makes it a bit easier.  It's all downloadable, but it's a monstrous download (several Gb).  I also know COM (a.k.a. gobbledegook) pretty well :P

Not sure how you'd go about synching things up.  Some of that API looks hopeful though.

Jim
Title: Re: speech in freebasic
Post by: Clyde on January 09, 2007
Thats awesome work Jim, welldone.
How would you go about changing the sound of the computers voice?

Cheers,
Clyde.
Title: Re: speech in freebasic
Post by: Shockwave on January 09, 2007
Nice one Jim  :) Have some of that Karma stuff!
Title: Re: speech in freebasic
Post by: psygate on January 09, 2007
Good Work! I will use that voice from now on a bit  ;D
Title: Re: speech in freebasic
Post by: Jim on January 09, 2007
Quote
How would you go about changing the sound of the computers voice?
I looked at that - there's a function called SetVoice in there, which will let you choose different speakers, male, female, robot, etc. but it takes pointers to a whole new class of objects, all as complicated as the ISpVoiceVtbl one.  So it'd be 2 or 3 times the work to make that happen.  But it's do-able.
The SetRate function gives a little bit of variation on the default voice.

Jim
Title: Re: speech in freebasic
Post by: Clyde on January 09, 2007
Ok, Cheers Jim.
Title: Re: speech in freebasic
Post by: Dr_D on January 10, 2007
Yeah, I played around with the set rate attribute. It's pretty funny. :D It looks like switching from the default voice would also require you to distribute the voice patch dll's with your demos. I could be wrong though.
Title: Re: speech in freebasic
Post by: Jim on January 10, 2007
I had a look at what would be required to make the voice change.  It's just far too much work for a mess about, it's a serious amount of work.  Sorry, but I'll have to leave that to someone else.

Jim
Title: Re: speech in freebasic
Post by: Paul on March 08, 2007
This is probably really cool but i cant get it to work.

: error 1: Argument count mismatch, found: '|'
CoCreateInstance(@CLSID_SpVoice, NULL, CLSCTX_ALL, @IID_ISpVoice, cast (any ptr, @voice))

Doing know what I'm doing wrong.

Edit, downloaded a newer version of free basic and now it works:)
Cool :D
Title: Re: speech in freebasic
Post by: Shockwave on March 09, 2007
Nice one :) Thanks for posting the solution.
Title: Re: speech in freebasic
Post by: Voltage on March 18, 2007
Great work Jim.   My daughter was a little bit freaked, but I like it.
Title: Re: speech in freebasic
Post by: Dr_D on March 18, 2007
hahaha! my daughter was a little freaked by it too, but she thought it was neat after a while. I sent it some children's text to help. :cheers:
Title: Re: speech in freebasic
Post by: Voltage on March 18, 2007
I had the thing singing "do the hokie pokie, and turn around"...   But its tempo threw her off a little :)  She's just learning (she is 25)....... kidding, she is nearly 2.
Title: Re: speech in freebasic
Post by: Jim on March 18, 2007
Must've sounded like Ned off South Park singing Kumbya.
Title: Re: speech in freebasic
Post by: ninogenio on October 21, 2007
i was wondering how i could get this going in dev c++ ive downloaded the redist SpeechSDK51MSM.exe from microsoft.

now is it just a case of linking my project to the libs and headers and will my compiled exe atomatically  be shipped with the required libs built in to run on other systems.

edit just unziped SpeechSDK51MSM.exe and its full of msm files?
Title: Re: speech in freebasic
Post by: Rbz on October 21, 2007
Quote
now is it just a case of linking my project to the libs and headers and will my compiled exe atomatically  be shipped with the required libs built in to run on other systems.
Yes, I think it will work on other XP config too.

Anyway try the attached file below, maybe it can help you.

Title: Re: speech in freebasic
Post by: Jim on October 21, 2007
I thought everything you need is in the platform SDK?  It should be relatively easy to port the basic FB stuff to C++.  Don't even think about doing it in C - you'll hit the same roadblock as I did with FB.  Doing COM in FB is painfull!
Jim
Title: Re: speech in freebasic
Post by: ninogenio on October 21, 2007
that works fine rbraz cheers mate,

@jim dev c++ doesnt come with sapi.h or the libs so i tryed dl the redist sdk but when i unzip it all i have is msm files that add up to 128 megs worth, so im not sure where to go.
Title: Re: speech in freebasic
Post by: Jim on October 22, 2007
The msm packages are probably no good to you.  They enable you to distribute the SAPI SDK itself, which isn't what you want to do.

Go here
http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&DisplayLang=en (http://www.microsoft.com/downloads/details.aspx?FamilyID=5e86ec97-40a7-453f-b0ee-6583171b4530&DisplayLang=en)
And download 'SpeechSDK51.exe'. 
Extract the zip and run setup.exe

You'll need to add
C:\Program Files\Microsoft Speech SDK 5.1\Include
C:\Program Files\Microsoft Speech SDK 5.1\Lib\i386
to the include/lib folders in DevC++

Jim
Title: Re: speech in freebasic
Post by: ninogenio on October 22, 2007
cheers jim!

i think im really close to getting something going but im getting two linker errors

  [linker error] undefined reference to `IID_ISpVoice'
  [linker error] undefined reference to `CLSID_SpVoice'

and when i try to include the sapi.lib under project->project options->parameters i get

  .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" ' unrecognized

ive looked around but cant see any other libs that are going to fix it up.

edit - actually  .drectve `/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" ' unrecognized
 is just a warning and it runs fine. guess it was never meant to run under dev c so a warning or two is expected.
Title: Re: speech in freebasic
Post by: Jim on October 22, 2007
Ignore that warning.  FB gives it too.  Microsoft are adding manufacturer specific chunks to the .obj/.lib files that other vendors don't understand (yet).

Jim