// DEPRECATED !!!  Óñòàðåâøèé êîìïîíåíò. Íå èñïîëüçîâàòü!

//{$I RPVISUAL.INC}
unit Sounds;

interface
(*
uses
  Classes, SysUtils, Dialogs;

Const
  TransLitSrc: ansistring = 'ÉÖÓÊÅÍÃØÙÇÕÚÔÛÂÀÏÐÎËÄÆÝß×ÑÌÈÒÜÁÞ¨éöóêåíãøùçõúôûâàïðîëäæýÿ÷ñìèòüáþ¸!@#$%^&*()_+|\`"¹?[]{};:"<>,./-= ';
  TransLitDst: ansistring = 'ICUKENGSSZHJFIVAPROLDZEYCSMITJBUEicukengsszhjfivaproldzeycsmitjbue__N_____________N___________._-__';

type
  StringArray = array of string;
  TSoundThread = class(TThread)
    function SpeakWavFile(FileName: string): Boolean;
    procedure TransliterateString(var s: string);
    function Speak(Name, Text: string): boolean;
  private
    FSoundQueue: string;
    FSoundQueueWrite: string;
    procedure GetSoundQueue;
    procedure SetSoundQueue;
    procedure splitMessage(mesidx: integer; tagidx: integer; var sounds: StringArray);
    function getSoundFilename(text: string): string;
  protected
    procedure Execute; override;
  public
    SoundDir: string;
    SoundQueue: string;
    procedure AddSoundQueue(s: string);
    function getMissingSounds: string;
    procedure produceSoundFile(text: String);
  end;

var
  soundProducerCommand: string = 'C:\Program Files\Balabolka\balabolka.exe -snmq "{text}" {file}';
*)
implementation
(*
uses
//  MesLogging,
  MesLoggingV1,
  Globals,
  MMSystem,
  Windows,
  HyperStr;


{ Important: Methods and properties of objects in VCL can only be used in a
  method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TSoundThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ TSoundThread }


// Play wav-file of the specified filename.
// If file is not found, tries to play 'system\nousound.wav'.
// If 'system\nousound.wav' is not found, plays 'alarm.wav'.
// Returns false, if 'alarm.wav' has been played. Otherwise returns true.
function TSoundThread.SpeakWavFile(FileName: string): boolean;
begin
//  if not SoundEnabled then exit;

  Result := true;
  Filename := SoundDIr + copy(Filename,1,32) + '.wav';

  if FileExists(FileName) then
    sndPlaySound(pchar(FileName), SND_SYNC)
  else begin
    Filename := SoundDIr + 'system\nosound.wav';
    if FileExists(FileName) then
      sndPlaySound(pchar(SoundDIr + 'system\nosound.wav'), SND_SYNC)
    else begin
      Filename := SoundDIr + 'alarm.wav';
      if FileExists(FileName) then
        sndPlaySound(pchar(filename), SND_SYNC);

      Result := false;
    end;
  end;
end;


procedure TSoundThread.TransliterateString(var s: string);
var
  i: integer;
begin
  Translate(s, TransLitSrc, TransLitDst);

  i := 1;
  while i <= length(s) do
    if copy(s, i-1, 2) = '__' then
      delete(s, i, 1)
    else
      inc(i);

  if copy(s, 1, 1) = '_' then delete(s, 1, 1);
  if copy(s, length(s), 1) = '_' then delete(s, length(s), 1);
end;


//============================================================================
// TEXT-TO-SPEECH
//============================================================================
function TSoundThread.Speak(Name, Text: string): boolean;
var
  k: integer;
  s: string;
begin
  Result := true;

  TransliterateString(Name);
  if not SpeakWavFile(Name) then begin
    Result := False;
    Exit;
  end;

  TransliterateString(Text);
  while length(Text) > 0 do begin
    k := pos('_', Text);
    if k = 0 then begin
      s := Text;
      Text := '';
    end else begin
      s := copy(Text, 1, k-1);
      delete(Text, 1, k);
    end;
    SpeakWavFile(s);
  end;
end;



//============================================================================
// THREAD
//============================================================================
procedure TSoundThread.Execute;
var
  l: cardinal;
  i,j: integer;
  flag: boolean;
  s: string;
begin
  SoundQueue := '';
  SoundDir := CurDir + '..\Sounds\';

  while not Terminated do begin
    l := GetTickCount;

    Synchronize(GetSoundQueue);
    i := 1;
    while true do begin
      s := trim(Parse(FSoundQueue, ';', i));
      if s='' then break;
      if s='delay' then
        sleep(1000)
      else
        SpeakWavFile(s);
    end;

    if (SoundEnabled) and (isMesConnected()) then begin

      flag := false;
      for i:=0 to length(Mess)-1 do begin

        for j:=0 to length(Mess[i].Tags)-1 do
          if (Mess[i].Tags[j].State = 1) and (not Mess[i].Tags[j].Spoken) then begin
//            Mess[i].Tags[j].Spoken := true;
            Mess[i].Tags[j].Spoken := Speak(Mess[i].Name, Mess[i].Tags[j].Descr);
//            SpeakWavFile('alarm');
            l := GetTickCount;
            flag := true;
            break;
          end;

        if flag then break;
      end;
    end;


   if (not SoundEnabled) and (MesConnected) then begin
     flag := false;
     for i:=0 to length(Mess)-1 do 
       for j:=0 to length(Mess[i].Tags)-1 do
         if (Mess[i].Tags[j].State = 1) then
           flag := true;
         
     if flag then
       AddSoundQueue('system\alarm;delay;delay;delay');
   end;



    repeat
      sleep(1)
    until (GetTickCount-l > 1000) or (Terminated);
  end;
end;


procedure TSoundThread.GetSoundQueue;
begin
  FSoundQueue := SoundQueue;
  SoundQueue := '';
end;

procedure TSoundThread.SetSoundQueue;
begin
  SoundQueue := SoundQueue + FSoundQueueWrite + ';';
end;

procedure TSoundThread.AddSoundQueue(s: string);
begin
  FSoundQueueWrite := s;
  Synchronize( SetSoundQueue );
end;

function TSoundThread.getMissingSounds: string;
var
  s: string;
  i,j,k: Integer;
  sa: StringArray;
  sl: TStringList;
begin
  sl := TStringList.Create();
  sl.Sorted := True;
  sl.Duplicates := dupIgnore;
  s := '';
  for i:=0 to length(Mess)-1 do begin
    for j:=0 to length(Mess[i].Tags)-1 do begin
      splitMessage(i, j, sa);
      for k:=0 to Length(sa)-1 do begin
        if not FileExists( getSoundFilename(sa[k]) ) then begin
          sl.Add(sa[k]);
        end;
      end;
    end;
  end;

  Result := sl.Text;
  sl.Free;
end;

function TSoundThread.getSoundFilename(text: string): string;
begin
  TransliterateString(text);
  result := SoundDIr + text + '.wav';
end;


procedure TSoundThread.splitMessage(mesidx: integer; tagidx: integer; var sounds: StringArray);
var
  n,k: Integer;
  s,ss: String;
begin
  n := 1;
  SetLength(sounds, n);
  s := mess[mesidx].Name;
  sounds[n-1] := s;

  ss := Trim( mess[mesidx].Tags[tagidx].Descr );
  while length(s) > 0 do begin
    k := pos(' ', ss);
    if k = 0 then begin
      s := ss;
      ss := '';
    end else begin
      s := copy(ss, 1, k-1);
      delete(ss, 1, k);
      ss := Trim(ss);
    end;
    Inc(n);
    SetLength(sounds, n);
    sounds[n-1] := s;
  end;

end;

procedure TSoundThread.produceSoundFile(text: String);
var
  F: TextFile;
  fname, s: String;
begin
  text := Trim(text);
  if text = '' then
    exit;
    
  fname := text;
  TransliterateString( fname );
  fname := SoundDIr + fname + '.wav';

  // invoke balabolka
  s := soundProducerCommand;
  ReplaceS(s, '{text}', text);
  ReplaceS(s, '{file}', fname);
  WinExec(PAnsiChar(AnsiString(s)), SW_NORMAL );

end;


*)
end.
