Question about a procedure

Hi,

I have a form with a listbox on it (lbVoices), where the speech-engines will be loaded.
and a small richedit (reText) where the user can enter text that he/she would like to test.
and a test-button (TestBtn). And 3 trackbars for the volume, pitch and rate
(tbVolume, tbRate and tbPitch).

I have this procedure for the TestBtn:

procedure TSettingsDlg.TestBtnClick(Sender: TObject);
begin
 If TestBtn.Caption = 'Test' then
 begin
   TestBtn.Caption := 'Stop';
   SpVoice1.Speak(reText.Text, SVSFlagsAsync);
 end else begin
   TestBtn.Caption := 'Test';
   SpVoice1.Skip('Sentence', MaxInt);
 end;
end;

This procedure works great. Only I forgot to tell
this procedure that he has to speak the selected item in the listbox (lbVoices)!!!
who knows the answer and is willing to help me.

P.
type
  TSettingsDlg = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    OKBtn: TButton;
    CancelBtn: TButton;
    HelpBtn: TButton;
    Label2: TLabel;
    Label7: TLabel;
    reText: TRichEdit;
    SpVoice1: TSpVoice;
    TestBtn: TButton;
    LbVoices: TListBox;
    tbRate: TTrackBar;
    tbVolume: TTrackBar;
    tbPitch: TTrackBar;
    StaticText1: TStaticText;
    StaticText2: TStaticText;
    StaticText3: TStaticText;
    lblRate: TLabel;
    lblVolume: TLabel;
    lblPitch: TLabel;
    procedure SpVoice1StartStream(ASender: TObject; StreamNumber: Integer;
      StreamPosition: OleVariant);
    procedure SpVoice1EndStream(ASender: TObject; StreamNumber: Integer;
      StreamPosition: OleVariant);
    procedure tbPitchChange(Sender: TObject);
    procedure tbRateChange(Sender: TObject);
    procedure tbVolumeChange(Sender: TObject);
    procedure TestBtnClick(Sender: TObject);
    procedure LbVoicesClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    SettingsFile: string;
    procedure LoadSettings;
    procedure SaveSettings;
  public
    { Public declarations }
  end;

var
  SettingsDlg: TSettingsDlg;

implementation

uses Main;

{$R *.dfm}

procedure TSettingsDlg.FormCreate(Sender: TObject);
var
  I: Integer;
  SOToken: ISpeechObjectToken;
  SOTokens: ISpeechObjectTokens;
begin
  SettingsFile := ChangeFileExt(Application.ExeName, '.ini');
  SpVoice1.EventInterests := SVEAllEvents;
  SOTokens := SpVoice1.GetVoices('', '');
  for I := 0 to SOTokens.Count - 1 do
  begin
    SOToken := SOTokens.Item(I);
    lbVoices.Items.AddObject(SOToken.GetDescription(0), TObject(SOToken));
    SOToken._AddRef;
  end;
  tbRate.Position := SpVoice1.Rate;
  lblRate.Caption := IntToStr(tbRate.Position);
  tbVolume.Position := SpVoice1.Volume;
  lblVolume.Caption := IntToStr(tbVolume.Position);
  LoadSettings;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to lbVoices.Items.Count - 1 do
  ISpeechObjectToken(Pointer(lbVoices.Items.Objects[I]))._Release;
  SaveSettings;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.LbVoicesClick(Sender: TObject);
var
  SOToken: ISpeechObjectToken;
begin
  begin
    SOToken := ISpeechObjectToken(Pointer(
      lbVoices.Items.Objects[lbVoices.ItemIndex]));
    SpVoice1.Voice := SOToken;
  end
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.LoadSettings;
var ini: TIniFile;
    defVoice: string;
begin
 ini := TIniFile.Create(SettingsFile);
 try
   defVoice := '';
   if lbVoices.Items.Count > 0 then
   defVoice := lbVoices.Items[0];
     lbVoices.ItemIndex := lbVoices.Items.IndexOf(ini.ReadString('Voice','Voice', defVoice));
     tbVolume.Position := ini.ReadInteger('Voice', 'Volume', SpVoice1.Volume);
     tbRate.Position := ini.ReadInteger('Voice', 'Rate', SpVoice1.Rate);
  finally
    FreeAndNil(ini)
  end;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.SaveSettings;
var ini: TIniFile;
    defVoice: string;
begin
  ini := TIniFile.Create(SettingsFile);
  try
  defVoice := '';
  if lbVoices.ItemIndex >= 0 then
  defVoice := lbVoices.Items[lbVoices.ItemIndex];
    ini.WriteString('Voice', 'Voice', defVoice);
    ini.WriteInteger('Voice', 'Volume', SpVoice1.Volume);
    ini.WriteInteger('Voice', 'Rate', SpVoice1.Rate);
  finally
    FreeAndNil(ini)
  end;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.SpVoice1EndStream(ASender: TObject;
  StreamNumber: Integer; StreamPosition: OleVariant);
begin
  TestBtn.Caption := 'Test';
  tbPitch.Enabled := true;
  tbVolume.Enabled := true;
  tbRate.Enabled := true;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.SpVoice1StartStream(ASender: TObject;
  StreamNumber: Integer; StreamPosition: OleVariant);
begin
  TestBtn.Caption := 'Stop';
  tbPitch.Enabled := false;
  tbVolume.Enabled := false;
  tbRate.Enabled := false;
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.tbPitchChange(Sender: TObject);
begin
  lblPitch.Caption := IntToStr(tbPitch.Position);
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.tbRateChange(Sender: TObject);
begin
  SpVoice1.Rate := tbRate.Position;
  lblRate.Caption := IntToStr(tbRate.Position);
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.tbVolumeChange(Sender: TObject);
begin
  SpVoice1.Volume := tbVolume.Position;
  lblVolume.Caption := IntToStr(tbVolume.Position);
end;
(*---------------------------------------------------*)
procedure TSettingsDlg.TestBtnClick(Sender: TObject);
begin
 If TestBtn.Caption = 'Test' then
 begin
   TestBtn.Caption := 'Stop';
   SpVoice1.Speak(reText.Text, SVSFlagsAsync);
 end else begin
   TestBtn.Caption := 'Test';
   SpVoice1.Skip('Sentence', MaxInt);
 end;
end;
(*---------------------------------------------------*)
end.

Open in new window

LVL 1
peterkiersAsked:
Who is Participating?
 
epasquierConnect With a Mentor Commented:
Ok, I though the double cast was not necessary. Return tou your old LbVoicesClick then
procedure TSettingsDlg.LbVoicesClick(Sender: TObject);
var
  SOToken: ISpeechObjectToken;
begin
 SOToken := ISpeechObjectToken(Pointer( lbVoices.Items.Objects[lbVoices.ItemIndex]));
 SpVoice1.Voice := SOToken;
end;

Open in new window

0
 
Geert GruwezOracle dbaCommented:
you question doesn't make sense

does it have to use the selected voice to speak the text from the rich edit ?
0
 
peterkiersAuthor Commented:
Your right. How dumb of me.

P.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
peterkiersAuthor Commented:
If my speechengines where loaded in a treeview instead of listbox my
problem would be solved. Do you know the answer?

P.
0
 
epasquierCommented:
Do you care if I rephrase what we think you asked ?

" This procedure should use the voice selected in the listbox (lbVoices) "

Well, I suppose that if you click in the listbox, the voice is selected by your LbVoicesClick method ( that can be simplified by the way, see below)

So it' might be possible that what you say is that AS LONG AS YOU DON'T CLICK ON A VOICE, the procedure above does not use the right voice. and that is because in your procedure TSettingsDlg.LoadSettings; when you set the listbox item index, it does not trigger the Click event as an onChange event would on a combo box. You have to call it manually after

procedure TSettingsDlg.LbVoicesClick(Sender: TObject);
begin
 SpVoice1.Voice :=  
   ISpeechObjectToken(lbVoices.Items.Objects[lbVoices.ItemIndex]);
end;

procedure TSettingsDlg.LoadSettings;
var 
 ini: TIniFile;
 defVoice: string;
begin
 ini := TIniFile.Create(SettingsFile);
 try
  if lbVoices.Items.Count > 0 
   then defVoice := lbVoices.Items[0]
   Else defVoice := '';
  lbVoices.ItemIndex := lbVoices.Items.IndexOf(ini.ReadString('Voice','Voice', defVoice));
  tbVolume.Position := ini.ReadInteger('Voice', 'Volume', SpVoice1.Volume);
  tbRate.Position := ini.ReadInteger('Voice', 'Rate', SpVoice1.Rate);
 finally
  FreeAndNil(ini);
 end;
 LbVoicesClick(lbVoices); // <== here set the selected voice
end;

Open in new window

0
 
peterkiersAuthor Commented:
If my speechengine would be loaded in a treeview, my problem is solved:
Here in this procedure the speechengines get loaded in a listview:

procedure TSettingsDlg.FormCreate(Sender: TObject);
var
  I: Integer;
  SOToken: ISpeechObjectToken;
  SOTokens: ISpeechObjectTokens;
begin
  SettingsFile := ChangeFileExt(Application.ExeName, '.ini');
  SpVoice1.EventInterests := SVEAllEvents;
  SOTokens := SpVoice1.GetVoices('', '');
  for I := 0 to SOTokens.Count - 1 do
  begin
    SOToken := SOTokens.Item(I);
    lbVoices.Items.AddObject(SOToken.GetDescription(0), TObject(SOToken));
    SOToken._AddRef;
  end;
  tbRate.Position := SpVoice1.Rate;
  lblRate.Caption := IntToStr(tbRate.Position);
  tbVolume.Position := SpVoice1.Volume;
  lblVolume.Caption := IntToStr(tbVolume.Position);
  LoadSettings;
end;

P.
0
 
peterkiersAuthor Commented:
sorry i ment listbox
0
 
peterkiersAuthor Commented:
OR what I ment by the question:

At the startup of my programm the speechengines are loaded into the listbox.
and one is selected from the inifile.
f.e: Anna
      Clair  <= Clair is selected
      Peter

When I press the TestBtn the programm uses the speechengine Anna
and not Clair!

When I choose one and the press the TestBtn, then i get right.
P.
0
 
epasquierCommented:
read my former post again. Your problem is that you don't call
 LbVoicesClick(lbVoices); // <== here set the selected voice

when you load the ini file
0
 
peterkiersAuthor Commented:
Incompatible types: ISpeechObjectToken and TObject

0
 
peterkiersAuthor Commented:
Thanks Espasquier this is the answer:

procedure TSettingsDlg.LbVoicesClick(Sender: TObject);
var
  SOToken: ISpeechObjectToken;
begin
  begin
    SOToken := ISpeechObjectToken(Pointer(
      lbVoices.Items.Objects[lbVoices.ItemIndex]));
    SpVoice2.Voice := SOToken;
  end
end;

procedure TSettingsDlg.LoadSettings;
...
  tbRate.Position := ini.ReadInteger('Voice', 'Rate', SpVoice2.Rate);
 finally
  FreeAndNil(ini);
 end;
 LbVoicesClick(lbVoices);  <==== I just had to add this
end;

Peter
0
 
peterkiersAuthor Commented:
500 points are comming to you...

Peter
0
All Courses

From novice to tech pro — start learning today.