[C++ Builder VCL] Make your applications talkative and listening applications by using SAPI ( Speech Synthesis & Speech Recognition)

by Jul 14, 2016

Let's make your C++ VCL applications talkative 😀 May be another wife  😀

This is my first blog post here so I start with stimulating an old Delphi article http://edn.embarcadero.com/article/29583 about Microsoft's SAPI library for Speech Synthesis & Speech Recognition which is edited by Brain Lang. So there is much more information about SAPI in this old article which is very helpful. If you want to do that on Delphi, please read Brain Lang's article.

More details about SAPI can be officially found here https://msdn.microsoft.com/en-us/library/ee125663(v=vs.85).aspx

and here https://msdn.microsoft.com/en-us/library/ee125077(v=vs.85).aspx


If you read and get some info from the links above now lets start to code our simple C++ Builder VCL example which will work on XE versions. 

Part I: Text To Speech in C++ Builder

1. Create a new C++ Builder VCL Project, add Edit and Button from component palette. Now we will add SAPI API (Type Library) as a component and its wrappers. Select Component->Import Component.. from the menu of C++ Builder as shown below

2. Select "Import a Type Library" and go Next

3. Type SAPI ( or you can type any category to the Palette Page and make sure  Generate Component Wrappers is checked as below


4. Select Microsoft Speech Library (be sure that it is sapi.dll) from Registered Type Libraries. My version is 5.4 on Windows 10, yours may be different

and go Next

6. Select "Add unit to …" and Finish

7. Click View Units or hit F12 you will see all units of your files. Now lets save all files to a folder that we know.

 SpeakingAPI Files

First Create a "SpeakingVCL" folder on your desktop or on your code projects folder. We will save everything to this SpeakingVCL folder. 

Select Unit1.cpp from the list by hitting F12 and save it as "SpeakingVCL_Unit1.cpp" to 

Select "SpeechLib_OCX.cpp" and "SpeechLib_TLB.cpp" and save both to folder in their names.

Now we can save this new project by Save Project As from menu with those new changes

save PCH file as "SpeakingVCL_Project1PCH1.h" and save project as "SpeakingVCL_Project1.cpp"

Now lets check your project folder it should be like this

8. Now select Unit1 to add Voice component and see your form by hitting (or double hit) F11. When we installed SAPI type library it is also added components to the SAPI category on your Component Palette (if you didn't type anything it may be found on ActiveX category). Or you can find them by typing "TSp" to the search of Component Palette.

Drag TSpVoice to your form and double click to Button1 and add lines inside  it to set Rate, Volume  of SpVoice1 and let it say

	Form1->SpVoice1->Rate=2; // Set Rate of Voice

	Form1->SpVoice1->Volume=100;  //Set Volume of Voice

	Form1->SpVoice1->Speak(Edit1->Text.w_str(), SpeechVoiceSpeakFlags::SVSFlagsAsync );  // Say Text and continue

    // if you want to wait speaking use this flag SpeechVoiceSpeakFlags::SVSFDefault

Now you can run your example by hitting F9


This simple full project can be found here SpeakingVCL. It doesnt work if you didn't add SAPI Type Lib as explained above.


Part II: Speech Recognition in C++ Builder VCL

1. Add Memo1 and another button (Button2) to your form to listen. Change caption of Button to "Listen"

    Drag  TSpSharedRecoContext1Recognition of SAPI from Components Palette to your form. You may also use TSpInprocRecognizer too.

2. Now lets obtain data when MS Speech Recognition is used. Select your SpSharedRecoContext1Recognition1 , go to events of this component, double click OnRecognition and  add this line inside 

   Memo1->Lines->Add( Result->PhraseInfo->GetText(0, -1, True) );

2. Go to SpeakingVCL_Unit1.h add ISpeechRecoGrammar *SRGrammar; to the public of Form1 as below. 

 public: // User declarations

__fastcall TForm1(TComponent* Owner);

ISpeechRecoGrammar *SRGrammar;


3. Back To Form1 double click to "Listen" captioned Button2 add these lines;

SpSharedRecoContext1->EventInterests = SpeechRecoEvents::SREAllEvents;


SRGrammar->CmdSetRuleIdState(0, SpeechRuleState::SGDSActive);


4. Your final Unit of Form1 will be like this


#include <vcl.h>
#pragma hdrstop

#include "SpeakingVCL_Unit1.h"
#pragma package(smart_init)
#pragma link "SpeechLib_OCX"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
void __fastcall TForm1::Button1Click(TObject *Sender)
	Form1->SpVoice1->Speak(Edit1->Text.w_str(), SpeechVoiceSpeakFlags::SVSFlagsAsync );  //SpeechVoiceSpeakFlags::SVSFDefault

void __fastcall TForm1::SpSharedRecoContext1Recognition(TObject *Sender, long StreamNumber,
		  Variant StreamPosition, SpeechRecognitionType RecognitionType,
		  ISpeechRecoResult *Result)
	Memo1->Lines->Add( Result->PhraseInfo->GetText(0, -1, True) );
void __fastcall TForm1::Button2Click(TObject *Sender)
	SpSharedRecoContext1->EventInterests = SpeechRecoEvents::SREAllEvents;

	SRGrammar->CmdSetRuleIdState(0, SpeechRuleState::SGDSActive);

5. Now you can test and run your application by hitting F9. That's all !

 Full project package can be found here SpeakingVCL2


To get better results you need to train MS Speech Recognition by your voice, also you might  need more tweaks. You may use other classes of SAPI too. In windows 10; there is Cortana speech recognition which works well with less number of languages supported, it is still under development. I can briefly say it is much more successful than MS Speech Recognition. But its API is not shared yet. It works on windows and uses your apps as a tool. There is a way to use Cortana by XAML or you can use cooperative running application with your VCL/FMX application. I am waiting new update on Windows 10. After that may be we can discuss this again.

On Android Google's Text To Speech & Recognition API is very successful. There is a wrapper example on Jim McKeeth's github on Delphi and C++ but it's components can be compiled on RADs only because of Delphi base.



On iOS i need time to check and test. May be someone adds here.


I hope these simple examples helps to your applications.

Please share your comments below and versions of your RADS.