Recent

Author Topic: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first  (Read 2300 times)

PawelO

  • New Member
  • *
  • Posts: 20
    • Polish railway traffic and interlocking simulator developed with Lazarus
Re: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first
« Reply #30 on: May 12, 2024, 01:51:40 pm »
I would do that following way.

1. Using TLB with SAPI interfaces instead of typing function names and arguments in blind. Gives error protection, code hints/autocompletion, clearly named types and consts, ...

2. Speaking in async mode, and sending next words to speak when last speaking is done (for example using TTimer).

Code: Pascal  [Select][+][-]
  1. unit uMain;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. // NOTE - to use SAPI + TLB:
  6. // 1. Install and use in project LazActiveX package
  7. // 2. Create SpeechLib_5_4_TLB (dll header): Tools -> Import Type Library ...:
  8. //    - browse for dll
  9. //    - select Create visual component (creates TAxc objects)
  10. //    - OK, save TLB file in project directory
  11. //
  12. // typical path to SAPI dll files:
  13. // C:\Windows\SysWOW64\Speech\Common\sapi.dll - 32bit
  14. // C:\Windows\System32\Speech\Common\sapi.dll - 64bit
  15.  
  16. interface
  17.  
  18. uses
  19.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, SpeechLib_5_4_TLB;
  20.  
  21. type
  22.  
  23.   TfrmMain = class(TForm)
  24.     Timer1: TTimer; //Interval = 100 ms
  25.     procedure FormCreate(Sender: TObject);
  26.     procedure Timer1Timer(Sender: TObject);
  27.   private
  28.     FSpVoice: TAxcSpVoice;
  29.     FSpeechVoice: ISpeechVoice;
  30.     FNextWordIndex: Integer;
  31.     { private declarations }
  32.   public
  33.     { public declarations }
  34.   end;
  35.  
  36. var
  37.   frmMain: TfrmMain;
  38.  
  39. const
  40.   WordsToRead: array of String = ('One', 'Two', 'Three', 'Four');
  41.  
  42. implementation
  43.  
  44. {$R *.lfm}
  45.  
  46. procedure TfrmMain.FormCreate(Sender: TObject);
  47. begin
  48.   //creating speaking object
  49.   FSpVoice := TAxcSpVoice.Create(Self);
  50.   FSpVoice.Visible := False; //to avoid appearing TAxc object on Form
  51.   FSpeechVoice := FSpVoice.OleServer; //for convinience
  52.  
  53.   //index of next word to speak
  54.   FNextWordIndex := 0;
  55. end;
  56.  
  57. procedure TfrmMain.Timer1Timer(Sender: TObject);
  58. begin
  59.   //speak next words when ready
  60.   if (FNextWordIndex <= High(WordsToRead)) and (FSpeechVoice.Status.RunningState <> SRSEIsSpeaking) then
  61.   begin
  62.     FSpeechVoice.Speak(WordsToRead[FNextWordIndex], SVSFlagsAsync);
  63.     FNextWordIndex += 1;
  64.   end;
  65. end;
  66.  
  67. end.
  68.  

jamie

  • Hero Member
  • *****
  • Posts: 6312
Re: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first
« Reply #31 on: May 12, 2024, 03:56:19 pm »
I've always had problems with importing libraries via Activex and if you get passed the import, then the defines may come out wroing.

etc.

 %)
The only true wisdom is knowing you know nothing

What I can do

  • Jr. Member
  • **
  • Posts: 60
Re: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first
« Reply #32 on: May 12, 2024, 11:34:19 pm »
hey guys there isn't much to this
.
first off I have a global unit uToolKit.pas has a few simple tools and I use it almost everywhere I even find it useful for debugging cause I don't have to break code during execution, I can just hear the audio and tell where the code is at and where it is going. So I like having everything about SayWord('text to say', gender); in a global unit and here is the kicker.
everything works fine in the IDE and calling SayWord works fine as long as I don't send consecutive calls in  a very short time (but only in a compiled EXE when reading through a list) The code is very simple. I really didn't think this was a very big deal. I figured a sleep or wait on routine would solve things. This works just fine but it would work much better is I could display the word in question and then speak the word  sort of like a simple flash card demo.  The whole concept is to control his computer time and see if I can teach him something in the process.  I would like to thank everyone I really do appreciate everything. I am not a coder buy any stretch of means but I just love to code thats all. I read a quoate that someone had up "Code first think second". You'll just get it going than do the cosmetics later.
I doing this for a kid that has been through tough times even with CPS and all sort of crap.  I just now got him to open up some. So you anything  of you guys can help, man I would love it.


KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first
« Reply #33 on: May 13, 2024, 12:17:05 am »
When you do the import way like PawelO wrote, there you have a lot more choices and options and crazy programmers stuff that might be over your current level to handle it correct.
Pawel0 just showed with the advanced import the legacy usage :D
I was posting two examples and just straight ask, did it not worked for you like you wanted it to be? Since here I can let it speak endless long different words without any problems that you describe.

My suggestion to your project would be, having some text files with your words that the little rascal needs to learn, maybe prepared in a little story.
Have a combobox to select the wordlist/story
Have a read-only memo to load and show the story
Have a set of 3 buttons, "Previous", "Current", "Next"
At startup, create a wordlist from line 0 (split by space) and select first word in memo plus replace "Current" with current word
Button "Current" = pressing it will speak the word, because its a button you can repeat that all-over again and again
Button "Previous" and "Next" is up to you to find out what they could be used for :D

If its more for elementary school kids, there also could be a wordlist index <-> graphic index involved, where for example the word "ball" could be loaded as a graphic displaying a "ball" .... and so on :D
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

What I can do

  • Jr. Member
  • **
  • Posts: 60
Re: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first
« Reply #34 on: May 13, 2024, 01:58:33 am »
I just finished the testing...
[hard crash] FSpVoice := TAxcSpVoice.Create(self);  Compiler Message states seft is unknown
[Hard crash] FSpVoice := TAxcSpVoice.Create(FSpVoice);
[Hard crash] FSpVoice := TAxcSpVoice.Create(nill);

how ever the winning prize goes to  "cdbc" just activate it once and it's done

Global unit...
Procedure ActivateSAPI;
begin
 SpVoice := CreateOleObject('SAPI.SpVoice');
end;
.....
form1.onCreate
...
ActivateSAPI;
everything works great.  LOL
I have an old saying I can't see the picture all I see is pixle dots, some times you just need to step back.
Speacial thanks to everyone

PawelO

  • New Member
  • *
  • Posts: 20
    • Polish railway traffic and interlocking simulator developed with Lazarus
Re: IDE SpVoice := CreateOleObject('SAPI.SpVoice'); How to test first
« Reply #35 on: May 13, 2024, 02:00:00 pm »
I just finished the testing...
[hard crash] FSpVoice := TAxcSpVoice.Create(self);  Compiler Message states seft is unknown
[Hard crash] FSpVoice := TAxcSpVoice.Create(FSpVoice);
[Hard crash] FSpVoice := TAxcSpVoice.Create(nill);

"Self" is the Owner of created object, that will automatically free it when it's destroyed itself (in my case TForm). If you are creating it in some global procedure, there is no "Self" indeed. But it should also work with "nil" (not "nill").

 

TinyPortal © 2005-2018