Recent

Author Topic: SpeechSynthesize  (Read 22697 times)

kogs

  • New Member
  • *
  • Posts: 42
SpeechSynthesize
« on: March 12, 2014, 04:28:53 pm »
Hi,

(Aphasia - http://en.wikipedia.org/wiki/Aphasia)

Mac OS X - yes, Linux, Window, etc. - no

unit SpeechSynthesize
...

SpeechSynthesize.txt -> SpeechSynthesize.pas

kogs
(Aphasia - http://en.wikipedia.org/wiki/Aphasia)
Mac OS X 10.9.1

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #1 on: March 12, 2014, 04:48:44 pm »
You probably don't need all the Carbon* and most of LCL units in the uses section.

But judging from the given link to the Wiki, you're probably asking why it doesn't work for you? Right?

Btw, I think there were speech synthesize APIs introduced in Windows XP for Accessibility purposes... and most likely there's already something in Linux.
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: SpeechSynthesize
« Reply #2 on: March 12, 2014, 04:59:36 pm »
@Skalogryz: I think he means he wants it to work on OSX and has no need for Linux or Windows synthesis.

Otherwise, he can use e.g. SAPI on windows:
http://wiki.lazarus.freepascal.org/SAPI#Use_with_Free_Pascal
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #3 on: March 12, 2014, 05:28:42 pm »
2 kogs, you could put Aphasia link to your "Signature" of your profile. In that case you won't need to put it at each thread you start.

So I see there were a few threads and posts made by you about SpeechSynthesize.
and I guess it still doesn't work for you, and you need it to work, right?

Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: SpeechSynthesize
« Reply #4 on: March 12, 2014, 06:01:13 pm »
Kogs is using Mac OS X 9.1

kogs

  • New Member
  • *
  • Posts: 42
Re: SpeechSynthesize
« Reply #5 on: March 12, 2014, 06:10:51 pm »
Signature - yes

SpeechSynthesize.txt -> SpeechSynthesize.pas -> logout -> login
 |
\/
(Aphasia - http://en.wikipedia.org/wiki/Aphasia)
Mac OS X 10.9.1

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #6 on: March 12, 2014, 06:13:08 pm »
Kogs is using Mac OS X 9.1
To be more correct Mac OS X 10.9.1 (Mavericks)
(there's no Mac OS X 9.1, there's Mac OS 9, but it is not supported by either FPC or Lazarus).

I don't know if OSX version should matter, it doesn't seem like anything was deprecated in the nsspeechsynthesizer
i'll try it tonight.
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #7 on: March 12, 2014, 06:13:59 pm »
SpeechSynthesize.txt -> SpeechSynthesize.pas -> logout -> login
Are you saying the synthesizer stops working after you log out and log back in?

(I'm assuming the application works in the background while logged out)
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

kogs

  • New Member
  • *
  • Posts: 42
Re: SpeechSynthesize
« Reply #8 on: March 12, 2014, 06:19:37 pm »
SpeechSynthesize - no

Code: [Select]
{$mode objfpc}{$H+}
{$modeswitch objectivec1}

interface

uses
  Classes, SysUtils, FileUtil, Controls, StdCtrls, ComCtrls, MacOSAll,
  Dialogs, CocoaAll, CarbonUtils, CarbonProc;

type

{ NSSpeechSynthesizer }
  NSSpeechSynthesizer = objcclass external (NSObject)
  private
    _privateNSSpeechSynthesizerVars: id;
    // function and procedure
    // init with voice
    function initWithVoice(voice_: NSString): id; message 'initWithVoice:';
    // Speaking
    function startSpeakingString(string_: NSString): Boolean; message 'startSpeakingString:';
//    function startSpeakingString_toURL(string_: NSString; url: NSURL): Boolean; message 'startSpeakingString:toURL:';
    function isSpeaking: Boolean; message 'isSpeaking';
    procedure stopSpeaking; message 'stopSpeaking';
//    procedure stopSpeakingAtBoundary(boundary: NSSpeechBoundary); message 'stopSpeakingAtBoundary:';
//    procedure pauseSpeakingAtBoundary(boundary: NSSpeechBoundary); message 'pauseSpeakingAtBoundary:';
    procedure continueSpeaking; message 'continueSpeaking';
//    function delegate: NSSpeechSynthesizerDelegateProtocol; message 'delegate';
//    procedure setDelegate(anObject: NSSpeechSynthesizerDelegateProtocol); message 'setDelegate:';
    // voice
    function voice: NSString; message 'voice';
    function setVoice(voice_: NSString): Boolean; message 'setVoice:';
    // rate
    function rate: single; message 'rate';
    procedure setRate(rate_: single); message 'setRate:';
    // volume
    function volume: single; message 'volume';
    procedure setVolume(volume_: single); message 'setVolume:';
//    function usesFeedbackWindow: Boolean; message 'usesFeedbackWindow';
//    procedure setUsesFeedbackWindow(flag: Boolean); message 'setUsesFeedbackWindow:';
//    procedure addSpeechDictionary(speechDictionary: NSDictionary); message 'addSpeechDictionary:';
    // phonemes from text
    function phonemesFromText(text: NSString): NSString; message 'phonemesFromText:';
//    function objectForProperty_error(property_: NSString; outError: NSErrorPointer): id; message 'objectForProperty:error:';
//    function setObject_forProperty_error(object_: id; property_: NSString; outError: NSErrorPointer): Boolean; message 'setObject:forProperty:error:';
//    class function isAnyApplicationSpeaking: Boolean; message 'isAnyApplicationSpeaking';
//    class function defaultVoice: NSString; message 'defaultVoice';
//    class function availableVoices: NSArray; message 'availableVoices';
//    class function attributesForVoice(voice_: NSString): NSDictionary; message 'attributesForVoice:';
  end;

  { TSpeechSynthesize }
  TSpeechSynthesize = class
  private
    SS: NSSpeechSynthesizer;
    function NSStr(const stringA: String): NSString;
    // Voice
    function GetVoice: String;
    procedure SetVoice(stringVoice: String);
    // Rate
    function GetRate: Integer;
    procedure SetRate(integerRate: Integer);
    // Volume
    function GetVolume: Integer;
    procedure SetVolume(integerVolume: Integer);
  public
    constructor Create;
    constructor Create(stringVoice: String);
    // Speaking
    function StartSpeakingString(stringA: String): Boolean;
    procedure StopSpeaking;
    function IsSpeaking: Boolean;  // speaking is yes/no
    procedure ContinueSpeaking;
    // Phonemes from text
    function PhonemesFromText(stringText: String): String;
    // Voice
    property Voice: String read GetVoice write SetVoice;
    // Rate
    property Rate: Integer read GetRate write SetRate;
    // Volume
    property Volume: Integer read GetVolume write SetVolume;
  end;

function NSStringToString(ns: NSString): String;

implementation

{-------------------------------------------------------------------------------
    function NSStringToString
-------------------------------------------------------------------------------}
function NSStringToString(ns: NSString): String;
begin
  Result := CFStringToStr(CFStringRef(ns));
end;

//------------------------------------------------------------------------------

{ TSpeechSynthesize }

{-------------------------------------------------------------------------------
    function NSStr
-------------------------------------------------------------------------------}
function TSpeechSynthesize.NSStr(const stringA: String): NSString;
 begin
   // converting string to NSString (CFStringRef and NSString are interchangable)
   Result := NSString(CFStr(PChar(stringA)));
 end;

{-------------------------------------------------------------------------------
    function StartSpeakingString
-------------------------------------------------------------------------------}
function TSpeechSynthesize.StartSpeakingString(stringA: String): Boolean;
begin
  Result := SS.startSpeakingString(NSStr(stringA));
end;

{-------------------------------------------------------------------------------
    procedure StopSpeaking
-------------------------------------------------------------------------------}
procedure TSpeechSynthesize.StopSpeaking;
begin
  SS.stopSpeaking;
end;

{-------------------------------------------------------------------------------
    function IsSpeaking
-------------------------------------------------------------------------------}
function TSpeechSynthesize.IsSpeaking: Boolean;
begin
  Result := False;
  Result := SS.isSpeaking;
end;

{-------------------------------------------------------------------------------
    procedure ContinueSpeakinG
-------------------------------------------------------------------------------}
procedure TSpeechSynthesize.ContinueSpeaking;
begin
  SS.continueSpeaking;
end;

{-------------------------------------------------------------------------------
    function GetVoice
-------------------------------------------------------------------------------}
function TSpeechSynthesize.GetVoice: String;
begin
  Result := NSStringToString(SS.voice);
end;

{-------------------------------------------------------------------------------
    procedure SetVoice
-------------------------------------------------------------------------------}
procedure TSpeechSynthesize.SetVoice(stringVoice: String);
begin
  SS.setVoice(NSStr(stringVoice));
end;

{-------------------------------------------------------------------------------
    function GetRate
-------------------------------------------------------------------------------}
function TSpeechSynthesize.GetRate: Integer;
begin
  Result := Integer(SS.rate);
end;

{-------------------------------------------------------------------------------
    procedure SetRate
-------------------------------------------------------------------------------}
procedure TSpeechSynthesize.SetRate(integerRate: Integer);
begin
  SS.setRate(single(integerRate));
end;

{-------------------------------------------------------------------------------
    function GetVolume
-------------------------------------------------------------------------------}
function TSpeechSynthesize.GetVolume: Integer;
begin
  Result := Integer(SS.rate);
end;

{-------------------------------------------------------------------------------
    procedure SetRate
-------------------------------------------------------------------------------}
procedure TSpeechSynthesize.SetVolume(integerVolume: Integer);
begin
  SS.setRate(Integer(integerVolume));
end;

{-------------------------------------------------------------------------------
    function PhonemesFromText
-------------------------------------------------------------------------------}
function  TSpeechSynthesize.PhonemesFromText(stringText: String): String;
begin
  Result := NSStringToString(SS.phonemesFromText(NSStr(stringText)));
end;

{-------------------------------------------------------------------------------
    constructor Create
-------------------------------------------------------------------------------}
constructor TSpeechSynthesize.Create;
begin
  inherited;
  SS := NSSpeechSynthesizer.alloc.init;
end;

constructor TSpeechSynthesize.Create(stringVoice: String);
begin
  SS := NSSpeechSynthesizer.alloc.initWithVoice(NSStr(stringVoice));
end;

end.                                                                 

ok

kogs
« Last Edit: March 12, 2014, 06:23:18 pm by skalogryz »
(Aphasia - http://en.wikipedia.org/wiki/Aphasia)
Mac OS X 10.9.1

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #9 on: March 12, 2014, 06:32:12 pm »
ah... it might be problem using the synthesizer with Carbon (used by default with OSX).
Synthesizer is based on AppKit framework (which is a backbone for Cocoa).

Try this: add link framework to the unit declaration. (unless you're already linking it through compiler options). It might not work though, and/or cause more problems.

Code: [Select]
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
interface

{$linkframework AppKit}

uses
  Classes, SysUtils, FileUtil, Controls, StdCtrls, ComCtrls, MacOSAll,
  Dialogs, CocoaAll, CarbonUtils, CarbonProc;
...

Though this mailing list shows that some one was able to use it  with Carbon
« Last Edit: March 12, 2014, 06:34:00 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #10 on: March 12, 2014, 06:40:16 pm »
Please try and let us know of your results:
A) it works.
B) it didn't compile (please paste the compiler error)
C) it did appear to compile, but didn't link (please paste the error)
D) it seems to be failing on start (the application icon shows up in the tray but then closes immediately.. the information could be found in "Logs" OSX utility)
E) something else...?

I'll try it tonight myself, but it will happen in 10 hours from now.
« Last Edit: March 12, 2014, 06:44:25 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

kogs

  • New Member
  • *
  • Posts: 42
Re: SpeechSynthesize
« Reply #11 on: March 12, 2014, 06:55:27 pm »
SpeechSynthesize.pas - yes!!!

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
  SpeechSynthesize;

type

  TMyThread = class(TThread)
  private
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: boolean);
  end;

  { TForm1 }

  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure MenuItem3Click(Sender: TObject);
    procedure MenuItem4Click(Sender: TObject);
  private
    aTh: TMyThread;
    SpeechSynthesize: TSpeechSynthesize;
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  SpeechSynthesize := TSpeechSynthesize.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SpeechSynthesize.Free;
end;

procedure TForm1.MenuItem3Click(Sender: TObject);
begin
  aTh := TMyThread.Create(False);
end;

procedure TForm1.MenuItem4Click(Sender: TObject);
begin
  SpeechSynthesize.StopSpeaking;
end;

//

procedure TMyThread.Execute;
begin
  Form1.MenuItem4.Enabled := True;;
  Form1.SpeechSynthesize.StartSpeakingString('i was the World, i was the World, i was the World,');
  while (not Terminated) and (Form1.SpeechSynthesize.IsSpeaking = True {any condition required}) do
  begin
    Sleep(5);
  end;
  Form1.MenuItem4.Enabled := False;
end;

constructor TMyThread.Create(CreateSuspended: boolean);
begin
  FreeOnTerminate := True;
  inherited Create(CreateSuspended);
end;

end.
                                   

kogs
« Last Edit: March 12, 2014, 06:57:44 pm by skalogryz »
(Aphasia - http://en.wikipedia.org/wiki/Aphasia)
Mac OS X 10.9.1

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #12 on: March 12, 2014, 06:58:49 pm »
SpeechSynthesize.pas - yes!!!
"yes" stands for A) or E) ?

Could you please attach the whole project?
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

kogs

  • New Member
  • *
  • Posts: 42
Re: SpeechSynthesize
« Reply #13 on: March 12, 2014, 07:28:45 pm »
A) yes

kogs
(Aphasia - http://en.wikipedia.org/wiki/Aphasia)
Mac OS X 10.9.1

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2268
    • havefunsoft.com
Re: SpeechSynthesize
« Reply #14 on: March 12, 2014, 07:39:53 pm »
A) yes
Perfect. I'm glad that linking framework helped.

A) Are there any issues with Unit1 you posted?
B) or you just posted it as an example of usage?
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz