unit NewSpectrum;

interface
uses   Math,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,ExtCtrls,
  Dialogs, StdCtrls,common,disco,Drawings;
const programDir:string='';
         InitDir:string='';

 type TWaveCaption = record
                      RiFF:array[1..4] of char;
                      fileLength:longWord;
                      Wave:array[1..4] of char;
                      fmt:array[1..4] of char;
                      lengthOfFmtData:longWord;
                      PCM:word;
                      MonoSter:word;
                      SampleRate:longWord;
                      blockAlign:longWord;
                      BACBS:word;
                      bits_sample:word;
                      wave_data:array[1..4] of char;
                      dataBlockLength:longWord;
                     end;
      TresArray = array of single;
  TOutputRecord = record                                       // 2th and the next records contain------------------------------0-th record contains-----------1-th record contains
                 out_sliceNbr : longWord;                      // portion number                                                number of portions
                  streamArray : array of TresArray;            // streams of vectors of resulted analysis
       phon,person,gender,age : char;                          // classification according to phonem, person gender and age     numbers of cathegory values
                          pF0 : single;
                  end;{record}  //--------------------------------check OutRecSize when you change this type !!!!!!!!!!!!!!!!!!!!
  TwaveCaptionArray = array[0..21] of smallInt;
            pathStr = string;  //z friend
            charSet = set of char;//z friend
             ExtStr = string[80];  //z friend
        TmeanVector = array of extended;                       //vector for retaining mean values
           THistory = array of TmeanVector;                    //history - vectors with components divided by averaging constant
 var                                    dataDir : pathStr='E:\apl\waver\results';
                                   waveFilePath : pathStr;
                                   cathFilePath : pathStr;
                    ReportFile, GaussSearchFile : textFile;
                              OutRecordFilePath : pathStr='E:\apl\spectrum\results\signal_spectra_and_cepstra.spc';
                                 ReportFilePath : pathStr='E:\apl\spectrum\results\signal_spectra_and_cepstra_report.txt';
                            GaussSearchFilePath : pathStr='E:\apl\spectrum\results\signal_spectra_and_cepstra_GaussSearchResults.txt';
                                       waveFile : byteFile;
                                           RIFF : string;
        fileLength,savedRec,prevSliceNbr, iGlob : longWord;
                                       Wave,fmt : string;
                     BACBS,bits_sample,personNr : byte;
                                      wave_data : string;
         T0, T0Fixed,blockAlign,lengthOfFmtData : word;
                                   PCM,MonoSter : byte;
                  spcSave, reportSave, gausSave : boolean;                 //save completed analysis results (zapisywać kompletne wyniki analiz)
                             frameNbr0,frameNbr : longint;
                                       melBasis : single=700;
                               tempus,nbrOfData : longword;
                                        manager : char;
                                       onScroll : boolean=false;
                                         filter : array of double;
                         temp,temp1,temp2,temp3 : variant;                  //debug prp.
                                       initFile : TextFile;
            breakLoad,T0TimeBack,timeBack,fixT0 : Boolean;
                                      reHistory : THistory;
ringBuffChangePointArr,frameNbrArr,frameNbr0Arr : array of integer;         //for multi CCR processing
                                 NbrOfMultiMean : byte=20;
                                   reHistoryArr : array of Thistory;        //for multi CCR processing
                                reMeanVectorArr : array of array of double; //for multi CCR processin
      PSrange0,PSrange,maxFrameNbr0,maxFrameNbr : word;
                  cpstrT0Fixed,cpstrT0,vPSstDev : single;
                             reTmp,imTmp,tmpArr : TdbArr;
                                         melIdx : array of word;
                                        melFreq : TdbArr;
                        Check2,windowsSearching : boolean;
                                     maxNbrOfEx : word=20;
                      cpstrPoint,jumpNbrSamples : word;//z disco2
                                         winNbr : byte;//z disco2
                                   outputRecord : ToutputRecord;
                                   nbrOfStreams : byte=0;
                  harmSpace, harmBiass, harmNbr : word;
                               angleTemp,rehist : int64; //debug angleSize, reHistory
                                    cathNameArr : array[1..4] of shortString;
                                    StreamNames : array of shortString;
                                            zn1 : char=#0;
                                    bundleColor : longInt;
                                    bundlePanel : byte;
                                    bundleRange : word;
                               totalSignalStDev : extended;
             fileDir,FileName,waveFileName,path : pathStr;  //28112023
                                 T0sliceNbrGlob : longint;

StreamsGraphColors : array[0..10] of longint=(clBlue,clBlue,clBlue,clBlack,clLime,clYellow,clRed,clBlue,clLime,clYellow,clRed);

procedure InitWrite;
procedure InitRead;
procedure NormCheckBoxesStatesToReport;
procedure spectrAnalyser(out nbrOfData:dword; var savedRec,prevSliceNbr:dword;callChain:string);
type TlabelSet=set of byte;
procedure labelsClear(labelSet:TlabelSet);
procedure showWaveHead(canvas:tcanvas;var waveFile:byteFile;  waveFilePath:string; out RIFF:string; out fileLength:longWord;
 out Wave,fmt:string; out lengthOfFmtData:word;out PCM,MonoSter:byte;out SampleRate:double; out blockAlign:word;
 out BACBS,bits_sample:byte; out wave_data:string; out dataBlockLength:longWord);
procedure ComputeFilter;
procedure outPutRecordInit(outputRecord:ToutputRecord; strNbr, strLength:word);
function WhatToSave(const firstCall:boolean):dWord;
procedure windowsSearch(const nbrOfData:dword;  annotation:boolean;callChain:string);
procedure slidesRecordInit;
procedure fft_par(edit,edit2:Tedit);
Procedure SaveCheckEnabler(enable:boolean);
function bundleStand:boolean;

implementation

 uses unit1,visualization,fft,grafiti4,spectanalisier,porto,cppDCT,ControlStatesEncoder;

  type
  TsingInt=array[0..1] of smallInt;                      // for smallint-single convert smallInt (vawe signal) and longint (e.g. sliceNbr, color) data and register it to sigle type file zapis dużych liczb całkowitych do pliku typu single
  TdwordArr = array of dword;
  Tencode = array[1..4] of char;
   TrealArray = array of single;
    TstepOutRecord = record                              // 7. i następne rekordy -----------------------
             slide_sliceNbr : longWord;                  // numer porcji
                     signal : TrealArray;                // porcja sygnału
              WeighedSignal : TrealArray;
                powerSpectr : TrealArray;                // spektrum mocy
                     vPSarr : TrealArray;                // variable power spectrum component
                     cPSarr : array of TrealArray;       // constant power spectrum component; cPS is an array of array because it gathers CCR results in the multi mode
                slide_angle : TrealArray;                // complex spectrum angle
             smoothedSpectr : TrealArray;                // spektrum j.w. wygładzone cepstralnie
            melSmoothSpectr : TrealArray;                // spektr j.w. po transformacji melowej
                powerCepstr : TrealArray;                // cepstrum mocy
                     vPCarr : TrealArray;                // variable power cepstrum component
                     cPCarr : TrealArray;                // variable power cepstrum component
                  melCepstr : TrealArray;                // invers fft transf. melSmoothSpectr
         phon,person,gender : char;                      // klasyfikacja wg fonemów, osób i plci
                        age : byte;                      //klasyfikacja wg wieku
                  end;{record}
TstandOutChecksStates = record rigid, weak : word end;  //14102023, 15112023

 var
                      stepOutRecord : TstepOutRecord;
                   OutPutRecordFile : file of single;
                             speech : array of smallInt;
                          personNbr : byte=0;
                            phonNbr : byte=0;
                          voicedNbr : byte=0;
                          genderNbr : byte=0;
                             ageNbr : byte=0;
                 phonSet, personSet,
                   genderSet,ageSet : charset;    //cathegory values sets
         half_win, clear, saveSlide : boolean;    //half_win - z disco2; , clear - czyszczenie wykresu w spcDraw i w oscDraw, saveSlide - zapisz slide
                          streamIdx : array[0..30] of byte=(255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255, 255, 255, 255, 255, 255, 255, 255);
                            cathNbr : byte=4;
               standOutChecksStates : TstandOutChecksStates;            //14102023, 15112023
                            warning : boolean = false; //14052024

Procedure SaveCheckEnabler(enable:boolean);
//desables and enables checkBoxes on the "Output" page
 Begin
  with form1 do
   begin  //--------output---------standardise----------------
     checkBox5.enabled:=enable;    checkBox29.enabled:=enable and checkBox5.checked;                               //input window
                             form2.checkBox82.enabled:=enable and (checkBox5.checked or form2.CheckBox7.Checked);
                             form2.checkBox83.enabled:=enable and (checkBox5.checked or form2.CheckBox8.Checked);
     checkBox40.enabled:=enable;   checkBox30.enabled:=enable and checkBox40.checked;                              //PS (Power Spectrum)
                             form2.checkBox84.enabled:=enable and (checkBox40.checked or form2.CheckBox9.Checked);
     checkBox4.enabled:=enable;                                                                                    //PS phase
     checkBox41.enabled:=enable;   checkBox31.enabled:=enable and checkBox41.checked;                              //sPS (cepstraly smoothed PS)
                             form2.checkBox85.enabled:=enable and (checkBox41.checked or form2.CheckBox10.Checked);
     checkBox42.enabled:=enable;   checkBox32.enabled:=enable and checkBox42.checked;                              //cPS (time constant PS contribution)
                             form2.checkBox88.enabled:=enable and (checkBox42.checked or form2.CheckBox13.Checked);
     checkBox43.enabled:=enable;   checkBox33.enabled:=enable and checkBox43.checked;                              //vPS (time variable PS contribution)
                             form2.checkBox87.enabled:=enable and (checkBox43.checked or form2.CheckBox12.Checked);
     checkBox44.enabled:=enable;   checkBox34.enabled:=enable and checkBox44.checked;                              //mel PS
                             form2.checkBox86.enabled:=enable and (checkBox44.checked or form2.CheckBox11.Checked);
     checkBox45.enabled:=enable;   checkBox35.enabled:=enable and checkBox45.checked;                              //PC  (Power Cepstrum)
                             form2.checkBox89.enabled:=enable and (checkBox45.checked or form2.CheckBox14.Checked);
     checkBox46.enabled:=enable;   checkBox36.enabled:=enable and checkBox46.checked;                              //cPC (time constant PC contribution)
                             form2.checkBox92.enabled:=enable and (checkBox46.checked or form2.CheckBox17.Checked);
     checkBox47.enabled:=enable;   checkBox37.enabled:=enable and checkBox47.checked;                              //vPC (time variable PC contribution)
                             form2.checkBox91.enabled:=enable and (checkBox47.checked or form2.CheckBox16.Checked);
     checkBox48.enabled:=enable;   checkBox38.enabled:=enable and checkBox48.checked;                              //mel PC
                             form2.checkBox90.enabled:=enable and (checkBox48.checked or form2.CheckBox15.Checked);
     checkBox49.enabled:=enable;  //checkBox39.enabled:=enable and checkBox49.checked;                              //multi-mean cPC
                            // form2.checkBox93.enabled:=enable and form2.checkBox59.checked;
   end;{with}
 End; {SaveCheckEnabler}

 procedure outRecordToFile(k:dword);
 (*
  TOutputRecord = record
                 out_sliceNbr : longWord;
                  streamArray : array of TresArray;
       phon,person,gender,age : char;
                          pF0 : single;
                  end;{record}
 *)
  type TcathArr = array[0..3] of char;    //array for conversion cathegory values
  var i,j:word;
  cathArr:TcathArr;
   Begin
    if not spcSave then exit;
    //result:=filePos(OutPutRecordFile);
    if not form1.CheckBox57.Checked then exit;   //save chosen streams
    try
     with OutputRecord do
      begin
       write(OutPutRecordFile,single(TsingInt(out_sliceNbr)));  //can also be: write(OutPutRecordFile,single(@out_sliceNbr)^);
       for i:=0 to nbrOfStreams-1 do
         for j:=0 to count div 2 do
           write(OutPutRecordFile,streamArray[i,j]);
       cathArr[0]:=phon; cathArr[1]:=person;cathArr[2]:=gender; cathArr[3]:=age;
       write(OutPutRecordFile,single(cathArr));
       write(OutPutRecordFile,pF0);
      end;
     except
      showMessage('Some programm error occured in the procedure "outRecordToFile" probably because the "nbrOfStreams" ='+intToStr(nbrOfStreams)+#13#10' is aequal to 0; program will be halted now even if not. Turn to the author.');
      halt;
     end;
    //result:=filePos(OutPutRecordFile);
   End;{outRecordToFile}

   function OutRecSize:word;    //size of record in bytes
    var k,m:word;
    begin
     result:=0;
     with  outPutRecord do     //-----------------------------find record size
      begin
       k:=sizeOf(out_sliceNbr);                            // portion number
       m:=sizeOf(streamArray[0,0]);                        // debug input
       k:=k+ m*nbrOfStreams*((count div 2)+1);             // streams of vectors of resulted analysis
       k:=k+4*sizeOf(phon);                                // classification according to phonem, person gender and age     numbers of cathegory values
       k:=k+sizeOf(pF0);                                   // F0 - fundamental frequency
      end;
     result:=k;
    end;

 function ampersandRemove(caption:shortString):shortString;
  var i:byte;
  begin
     i:=0;                                               //delete &
    while i<byte(caption[0]) do
     begin
      inc(i);
      if caption[i]='&' then begin delete(caption,i,1); dec(i) end;
     end;{del&}
   ampersandRemove:=caption;
  end;

 procedure SaveCathNames(k:word; var singleArr:array of single);
  var i : dword;
  begin;
    if not spcSave then exit;
    //result:=filePos(OutPutRecordFile);
    temp1:=high(singleArr);
    if not form1.CheckBox57.Checked then exit; //save chosen streams
    try
    for i:=0 to k-1 do write(OutPutRecordFile,singleArr[i]);
    temp:=i;
    except
     showMessage('Some error occured in the procedure "SaveCathNames".'#13#10'It failed at the point '+intToStr(i)+
     ' while writing down the output path.'#13#10'There was to write '+intToStr(k-1)+'sings into the array "singleArr". Its capacity was '+intToStr(temp1));
    end;
  end;{SaveCathNames}

 procedure cathNamesDescr(k:word);

 function stringShorter(var strArr:array of shortString;  NbrOfStr,maxLengthSumm:word):string;
  procedure shortStringsUnsorted(var strLengthArr:array of byte; const NbrOfStr,maxLengthSumm:word; var lengthSum:word);
  var i1,j, level:word;
  Begin
   level:=0;
   for i1:=0 to NbrOfStr-1 do //find max length
   if level<strLengthArr[i1]
   then level:=strLengthArr[i1];
   while (level>1) and (lengthSum>maxLengthSumm) do
   BEGIN //level lowering
    i1:=0;
    while (lengthSum>maxLengthSumm) and (i1<NbrOfStr) do   //i mod NbrOfStr; //pierscien
     Begin
      j:=(NbrOfStr-(i1 mod NbrOfStr))-1;  //przegladaj od konca
      while (strLengthArr[j]>=level) and (lengthSum>maxLengthSumm) do
       begin
        dec(strLengthArr[j]);
        dec(lengthSum);
       end; {while}
      inc(i1);
     End; {while}
     dec(level);
    END;{while}
  End;{shortStringsUnsorted}

 var        i,k : byte;
  shortedStrArr : array of shortString;
   strLengthArr : array of byte;
      lengthSum : word;
Begin  //-------------------------------stringShorter-----------
 result:='';
 setLength(shortedStrArr,NbrOfStr);
 setLength(strLengthArr,NbrOfStr);
 lengthSum:=0;
 for i:=0 to NbrOfStr-1 do //find max length
  begin
   strLengthArr[i]:=length(strArr[i]);
   lengthSum:=lengthSum+strLengthArr[i];
   shortedStrArr[i]:=strArr[i];
  end;
  form1.Label15.Caption:='Total length='+intTostr(lengthSum);
  shortStringsUnsorted(strLengthArr,NbrOfStr,maxLengthSumm,lengthSum);
  for i:=0 to NbrOfStr-1 do
   length(shortedStrArr[i]):=strLengthArr[i];
  with form2 do
  begin
   label64.caption:=shortedStrArr[0];
   label66.caption:=shortedStrArr[1];
   label70.caption:=shortedStrArr[2];
   label5.caption:=shortedStrArr[3];
  end;
  lengthSum:=0; k:=1;
  for i:=0 to NbrOfStr-1 do   //make one string containing all cath names separated by #0
  begin
   lengthSum:=lengthSum+length(shortedStrArr[i])+1;
   if lengthSum<maxLengthSumm then result:=result+shortedStrArr[i]+#0
   else
    begin //last chain can not be ended with the "#0"
     dec(lengthSum,length(shortedStrArr[i])+1);
     while lengthSum<=maxLengthSumm do
       begin
        inc(lengthSum);
        result:=result+shortedStrArr[i,k];
       end;{while}
     dec(lengthSum); break;
    end {else}
  end;
 setLength(shortedStrArr,0);
 setLength(strLengthArr,0);
End;{stringShorter}

 var
                 i,l : longword;
                   j : byte;
                   s : string;
              encode : Tencode;
           singleArr : array of single;
  Begin  //==============================================================cathNamesDescr=======================
   k:=OutRecSize; //i:=filePos(OutPutRecordFile);    //i for debug prp.
   if k mod 4<>0 then showMessage('There is something wrong with the TOutRecord or the size of this is bad counted, as it should be a multiplication of single type size, i.e. 4'#13#10'Turn to the author');
   setLength(singleArr,(k div 4)+1);
   s:=stringShorter(cathNameArr,cathNbr,k-cathNbr);
   for i:=0 to high(singleArr) do singleArr[i]:=0;
   i:=0; l:=length(s);
   while i<=k-1 do
    begin
     for j:=1 to 4 do
      begin
       encode[j]:=#0;//aby poprawnie zakodowac koncowke nie stanowiaca pelnych 4 znakow
       if i+j<=l then encode[j]:=s[i+j];
      end;{for}
     if (i div 4)<high(singleArr) then
      singleArr[i div 4]:=single(encode)
     else showMessage('Program error occured in procedure "cathNamesDescr"'#13#10'i div 4='+intToStr(i div 4)+' exceedes high(singleArr)='+intToStr(high(singleArr))+' program should be breaken');
     inc(i,4);
    end;{while}
   SaveCathNames(k div 4,singleArr);  //result:=filePos(OutPutRecordFile); i for debug prp.
   //i:=filePos(OutPutRecordFile);    //for debug prp.
  End;{cathNamesDescr}

 Procedure FileNameEncode(s:string);

 var
             i,j,k,l : dword;
              encode : Tencode; // Tencode = array[1..4] of char;
           singleArr : array of single;
  Begin  //====================================FileNameEncode============================
   k:=OutRecSize;
   i:=filePos(OutPutRecordFile);    //i for debug prp.
   l:=length(s);
   if k mod 4<>0 then showMessage('There is something wrong with the TOutRecord or the size of this is bad counted, as it should be a multiplication of single type size, i.e. 4'#13#10'Turn to the author');
   setLength(singleArr,(k div 4)+1);
   if l>k then s:=copy(s,l-k+1,k);  //copy ending of the string to save it in case when size of the outputRecord is too small to contain full string
   if k<l then showMessage('Streams are too short to register full path, i.e. the path "'+s+'" will be saved as "'+s+'"');
   for i:=0 to high(singleArr) do singleArr[i]:=0;
   i:=0;
   l:=length(s);
   try
    while i<=k-1 do
     begin
      for j:=1 to 4 do
       begin
        encode[j]:=#0;//aby poprawnie zakodować koncówkę nie stanowiącą pełnych 4 znaków
        if i+j<=l then encode[j]:=s[i+j];
       end;{for j}
       if (i div 4)<high(singleArr) then
        singleArr[i div 4]:=single(encode)
       else showMessage('Program error occured in procedure "FileNameEncode"'#13#10'i div 4='+intToStr(i div 4)+' exceedes high(singleArr)='+intToStr(high(singleArr))+' program should be breaken');
      inc(i,4);
     end;{while i}
    SaveCathNames(k div 4,singleArr);  //result:=filePos(OutPutRecordFile); i for debug prp.
    i:=filePos(OutPutRecordFile);      //for debug prp.
   except
    ShowMessage('Some error occured in the proc. "FileNameEncode"');
   end; {try}
  End;{FileNameEncode}

  procedure AnalysisParamRegisterToReport;
   type TparamRec=record pWinShape,pF0WinShape, p0component, pJump:byte; end;

   var   i, recSize : longword;
           paramRec : TparamRec;
                 ic : byte; //streamNames counter
 Begin      //--------------------------------AnalysisParamRegisterToReport------------------------------------
  writeln(reportFile,'Analysis parameters:');
  recSize:=OutRecSize;
  i:=1;
  with outPutRecord do   //--------------------------------------write down parameters of analysis at the first record
   begin
    writeln(reportFile,i:3,') number of streams ', nbrOfStreams,', i.e. (stream name):');
    for ic:=0 to nbrOfStreams-1 do writeln(reportFile,'    > ',streamNames[ic]); writeln(reportFile);
    inc(i);
    F0Count:=count;
    writeln(reportFile,i:3,') windows width  for F0 measurements ',F0Count,' (temporary value accepted until windows width and shape for F0 measurements will be developed)');
    inc(i);
    writeln(reportFile,i:3,') Size of records ',recSize,' bytes');
    inc(i);
    writeln(reportFile,i:3,') Jump nbr samples ',jumpNbrSamples,' samples');
    inc(i);
   with paramRec do
    begin
     pWinShape:=  form1.RadioGroup7.ItemIndex;
     writeln(reportFile,i:3,') weighting windows shape used for spectrum analyses nbr ',pWinShape, ' i.e. ',ampersandRemove(form2.RadioGroup7.Items[form2.RadioGroup7.ItemIndex]));
     inc(i);
     p0component:=byte(form2.checkBox30.Checked);
     write(reportFile,i:3,') "',form2.checkBox30.caption,'" , i.e. 0-th component of these streams =0? - '); if p0component=0 then writeln(reportFile,'no') else writeln(reportFile,'yes');
     inc(i);
     writeln(reportFile,i:3,') filter nbr ',form1.RadioGroup2.ItemIndex);
     inc(i);
     pF0WinShape:=pWinShape; //temporary encoding
     writeln(reportFile,i:3,') weighting windows shape nbr used for F0 measurements ', pF0WinShape,
      ' i.e. ',ampersandRemove(form2.RadioGroup7.Items[form2.RadioGroup3.ItemIndex]), //radio7 because radio 3 has no labels
      ' (temporary value accepted until windows width and shape for F0measurements will be developed)');
     inc(i);
     with form2 do
      writeln(reportFile,#13#10,i:3,') There was analysed '+label61.caption+' of '+label11.caption+
                         ' samples, i.e. '+label63.caption+' of '+label30.caption+' slices.');
    end;{with}
    inc(i);
    writeln(reportFile,i:3,') number of the "',cathNameArr[1],'" values ', phonNbr);
    inc(i);
    writeln(reportFile,i:3,') number of the "',cathNameArr[2],'" values ',personNbr);
    inc(i);  //number of persons (liczba osób)
     writeln(reportFile,i:3,') number of the "',cathNameArr[3],'" values ',genderNbr);
    inc(i);
    writeln(reportFile,i:3,') number of the "',cathNameArr[4],'" values ',ageNbr);
    inc(i);
    writeln(reportFile,i:3,') rate=', rate:5:0);
    inc(i);
    writeln(reportFile,i:3,') basic average frames (for vPS, cPS, vPC, cPC)=',frameNbr);
    if form1.CheckBox49.Checked then
     try
      writeln(reportFile,'CCR bundle="',form1.radiogroup4.Items[form1.radiogroup4.ItemIndex],'"', '; number of multimean=',nbrOfMultimean);
      writeln(reportFile,'Averaging constants:');
      for ic:=0 to nbrOfMultimean-1 do write(reportFile,#9,frameNbrArr[ic]);writeln(reportFile);
     except
     end;{try}
    flush(reportFile);
   end;{with}
 End;{AnalysisParamRegisterToReport}

 function AnalysisParamRegister(const firstCall:boolean):longWord;
   type TparamRec=record pWinShape,pF0WinShape, p0component, pJump:byte; end;
        TcountsRec=record rCount1, rCount2 : word end;
        TratePeriods=record rRate:word;rNumberOfMultiMean, rFrameNbr:byte end;
   var   i, recSize : longword;
           paramRec : TparamRec;
          countsRec : TcountsRec;
        ratePeriods : TratePeriods;
 Begin      //--------------------------------AnalysisParamRegister------------------------------------
  if not spcSave then exit;                  //exit if the file was not opened for writing
 // result:=filePos(OutPutRecordFile);        //for debug prp.
  recSize:=OutRecSize;
 (* i:=filePos(outPutRecordFile);           //for debug prp.
  if i<>0 then
   if not windowsSearching then         //do not show this message when widows searching is performed
    begin
     showMessage('Number of streams or some other parameters were changed; the output file (its position='+intToStr(filePos(outPutRecordFile))+
                 ') will be overwritten from scratch and filled with current results'#13#10'It is a programm error if it was not the case!');
     manager:='E';  //change in output streams, begin analysis from scratch
    end; *)
  with countsRec do begin rCount1:=count; rCount2:=nbrOfStreams end;
  i:=0;
  with outPutRecord do   //--------------------------------------write down parameters of analysis at the first record
   begin
    out_sliceNbr:=longWord(countsRec);                       //number of streams (liczba strumieni)
    try         F0Count:=count;                              //temporary value accepted until windows width and shape for F0 measurements will be developed
     with countsRec do begin rCount1:=recSize; rCount2:=F0Count end;
     streamArray[0,0]:=single(countsRec);           inc(i);
     with paramRec do
      begin
       pWinShape:=  form1.RadioGroup7.ItemIndex;    inc(i);  //weighting windows shape
       pF0WinShape:=pWinShape;                      inc(i);  //weighting windows shape used for F0 measures; temporary value accepted until windows width and shape for F0measurements will be developed
       p0component:=byte(form2.checkBox30.Checked); inc(i);  //0-th component:=0  (this info is repeated in checkBoxEnCode 15112023)
       pJump:=jumpNbrSamples;                       inc(i);  //jump
      end;{with}
     streamArray[0,1]:=single(paramRec);
     with standOutChecksStates do   //15112023
      begin
       rigid:=allNormChecksStatesCode;       //rigid, weak has here nothing to do with their meanings in C and D arrays
       weak:=allOutChecksStatesCode
      end;
    streamArray[0,2]:=single(standOutChecksStates);
     if high(streamArray[0])>=2 then streamArray[0,2]:=single(standOutChecksStates);     //26092023
    except
     showMessage('Subroutine "AnalysisParamRegister" stopped at '+intToStr(i)+'. Probably streams are too short'+
      ' (='+intToStr(count div 2)+' points, it is needed however 4 at least.)'#13#10+
      'Some analysis parameters will not be recorded.'#13#10'"AnalysisParamRegister" is a procedure, which'+
      ' registers into the *.spc analysis results file all parameters of the analysis.'#13#10+
      'It goes to the very begining of the file to do it. Final registering is done after analysis are finished.');
    end;
    phon:=char(phonNbr);                            inc(i);  //number of phonems (liczba fonemów)
    person:=char(personNbr);                        inc(i);  //number of persons (liczba osób)
    gender:=char(genderNbr);                        inc(i);  //numbers of genders (liczba płci)
    age:=char(ageNbr);                              inc(i);  //number of age groups (liczba grup wiekowych)
    with ratePeriods do
     begin
      rRate:=round(rate); rNumberOfMultiMean:=NbrOfMultiMean; rFrameNbr:=frameNbr;
     end;{with}
    pF0:=single(ratePeriods);                       inc(i,3); //TratePeriods=record pRate:word;pNumberOfMultiMean, pStandMean:byte end;
   end;{with}
   OutRecordToFile(1);                                         //1-th, record of the analysis parameters (zapis rekordu parametrów analizy)
   cathNamesDescr(recSize);                                 //2-nd, record of cathegories names; saved in the cathNamesDescr with statement i:=SaveCathNames(k div 4,singleArr);
   try
    if not firstCall then AnalysisParamRegisterToReport
   except
    showMessage('[AnalysisParamRegister], Could not write analysis parameters to report file. The report file probably was  not opened. Debug program or turn to the author.')
   end;
 End;{AnalysisParamRegister}

 procedure SaveMultiMeanList;
  type      TtimArr=array[0..3] of byte;
         TsingleArr=array of single;
  var i,j,k,recSize:word;
             timArr:TtimArr;
          singleArr:TsingleArr;
  Begin
   recSize:=OutRecSize;  k:=0;
   setLength(singleArr,recSize div 4);
   for i:=0 to nbrOfMultiMean do
    begin
     j:=i mod 4;
     timarr[j]:=frameNbrArr[i];
     if j=3 then
      begin
       singleArr[k]:=single(timArr);
       inc(k);
      end;
    end;{for i}
   SaveCathNames(recSize div 4,singleArr);  //result:=filePos(OutPutRecordFile); i for debug prp.
  End;{saveMultiMeanList}

  procedure saveCathSets;
   type     TsetSingle= array[0..7] of single;
         TsetSingleArr= array[0..3] of TsetSingle;
   var setSingleArr:TsetSingleArr;
       singleArr:array of single;
    k,i,j,l:word;
   Begin
    l:=outRecSize div 4;
    setLength(singleArr,l);
    setSingleArr[0]:=TsetSingle(phonSet);
    setSingleArr[1]:=TsetSingle(personSet);
    setSingleArr[2]:=TsetSingle(genderSet);
    setSingleArr[3]:=TsetSingle(ageSet);
    i:=0;k:=0;
    while i<l do //copy encrypted sets to singleArr
     Begin
      if k<4 then
       begin
        j:=i mod 8;
        singleArr[i]:=setSingleArr[k,j];
        if j=7 then inc(k);
        inc(i);
       end
      else break;
     End;{while}
     k:=high(singleArr);
     for j:=i to l-1 do   //fill up the array with 0's
      singleArr[j]:=0;
     SaveCathNames(l,singleArr);
   End;{saveCathSets}


  procedure outPutRecordInit(outputRecord:ToutputRecord; strNbr, strLength:word);
   var i,j:word;
   Begin
     with outputRecord do
      begin if (strNbr<=0) or (strLength<=0) then exit;
       out_sliceNbr:=high(out_sliceNbr);
       for i:=0 to strNbr-1 do
        for j:=0 to strLength-1 do
         streamArray[i,j]:=maxSingle;
      phon:=#0; person:=#0; gender:=#0; age:=#0;
      pF0:=maxSingle;
     end;{with}
   End;{outPutRecordInit}

  function bundleStand:boolean;
  Begin
   result:=false;
   if form2.checkBox45.Checked then
   with form2 do
   case radiogroup4.ItemIndex of
    0: result:=checkBox87.Checked;
    1: result:=checkBox88.Checked;
    2: result:=checkBox91.Checked;
    3: result:=checkBox92.Checked
   end;
  End;{bundleStand}

 function WhatToSave(const firstCall:boolean):dWord;
  type TPanelDecHalfRev = record rPanelNbr,rDecimals:byte; rHalf,rRev:boolean; end;

  var PanelDecHalfRev : TpanelDecHalfRev;    //panelNbr, decimals points, half graph (only positive|negative Y axis), rev - direction of Y axis
    F0PanelDecHalfRev : TPanelDecHalfRev;

                         // 1                        2                 3                        4                   5   6
  procedure streamsDescr(caption:shortString;const stand:boolean;var stream:TresArray; const  panelNbr:byte; const xSc,ySc:word;
   const color:longint; const decimals:byte; const Half,rev:boolean; var ic:byte;var tmpOutRecStream:TresArray;
   //     7                     8                    9   10               11            12
   const check:TcheckBox; out newCaption:shortString;RigidChecksStates,weakChecksStates:word);
   //    13                   14                     15                        16
  //introduces stream name into a stream instance  and registers visual parameters (for a stream's graph)
  //the visual parameters are introduced also into stream instances of a temporary output record instance
  //valStandCommChecks=valid Standardize Command Check Boxes
  //ic - streams names counter
   type
    TsingleInfo=array[1..64] of single;
      TtextInfo=array[1..256] of char;
            Txy=record x,y:word end;

   var    i,j,k,l : word;
               xy : Txy;
         textInfo : TtextInfo;
       singleInfo : TsingleInfo absolute textInfo;
                s : shortString;
   Begin   //========================================== streamsDescr ============================
    //for i:=1 to pos('.',caption) do delete(caption,1,1);   //delete trailing numbering of streams in interface
   // while caption[1]=' ' do delete(caption,1,1);
    caption:=ampersandRemove(caption);     //ampersand delete
    k:=pos('.',caption)+2;
    if stand and (caption[k]<>'$') then insert('$',caption,k);
    if not stand and (caption[k]='$') then delete(caption,k,1);
    j:=length(caption);                   //if j>count div 2 then j:=count div 2;
    k:=sizeOf(stream[0]);
    l:=sizeof(singleInfo[1]);
    if k<>l then
     begin
      showMessage('Procedure "streamsDescr"'#13#10'Different sizes of stream and temporary array components.'+
      #13#10'Streams name, i.e. '+caption+' can not be inserted');
      exit;
     end;
    with PanelDecHalfRev do begin rPanelNbr:=panelNbr; rDecimals:=decimals; rHalf:=half; rRev:=rev; end;
    with standOutChecksStates do   //14102023
     begin
      rigid:=RigidChecksStates;
      weak:=weakChecksStates
     end;
    l:=high(stream);
    if j+1>k*(l+1) then  j:=k*(l+1)-1;        //name shortening when is too long
    for i:=1 to j do textInfo[i]:=caption[i]; //absolute singleInfo!
    inc(j); textInfo[j]:=#0;
    l:=j div k;
    if j mod k>0 then inc(l);
    k:=l; l:=0;
    for i:=0 to k-1 do
     begin
      stream[i]:=singleInfo[i+1];             //absolute textInfo!
      inc(l);  //debup prp
     end;{for}
    if l*sizeOf(stream[0])<j then
     showMessage('A stream name "'+caption+'" was not registered completely');
    //visual parameters
    l:=high(tmpOutRecStream);
                 tmpOutRecStream[0]:=single(PanelDecHalfRev);
    with xy do begin x:=xSc; y:=ySc end;
    if l>=1 then tmpOutRecStream[1]:=single(xy);
    if l>=2 then tmpOutRecStream[2]:=single(TsingInt(color));
    try  //14052024
     if l>=2 then tmpOutRecStream[3]:=single(standOutChecksStates);//  14102023
    except
     if not warning then
     showMessage('Due to too small windows width (='+intToStr(count)+') data "standOutChecksStates" pertaining settings of the "'
      +form2.label2.Caption+'" and the "'+form2.label6.Caption+'" check boxes could not be transfered'#13#10'Any other analysis will be still correct.');
     warning:=true;
    end;
    StreamNames[ic]:=caption;                //stream names are sent to report
    inc(ic);
    newCaption:=caption;
    check.Caption:=copy(newCaption,1,pos('.',newCaption));
    if form2.checkBox45.Checked then form2.checkBox45.Caption:=check.Caption+'Multi Mean'; 
    s:=check.Caption;
    if stand then insert('$',s, pos('.',newCaption)+1);
    check.Caption:=s;
   End; {streamsDescr}

   procedure F0PlotDescr(var outputRecord:ToutputRecord;var F0PanelDecHalfRev:TPanelDecHalfRev;const decimals:byte; const Half,rev:boolean; const xRange,yRange:word);
    type              Txy = record x,y:word end;
    var                xy : Txy;

   Begin
    with F0PanelDecHalfRev do begin rPanelNbr:=1; rDecimals:=decimals; rHalf:=half; rRev:=rev end;
    xy.x:=xRange; xy.y:=cpstrPoint;//yRange;  220219
    with outputRecord do
     begin
      out_sliceNbr:=longWord(F0PanelDecHalfRev);
      pF0:=single(xy);
     end;{with}
   End;{F0PlotDescr}

 var i:integer; ic:byte;      //ic - streams names counter
     newCaption:shortString;
  tmpOutputRecord:ToutputRecord;

 Begin  //------------------------------ WhatToSave ---------------------------------
  if not spcSave then
   begin
    ShowMessage('[WhatToSave] Error: The output record file is not opened; turn to the author or find the reason in the program code.'#13#10'Probably nothing will be saved or saved without content description');
    exit;//debug, do usunięcia lub dać na początku
   end;
  nbrOfStreams:=0;
  try  // Part 1.
   with form1 do
    begin  //------------------assign index to a stream
     //--Form1.Out check boxes--------------------------
     if checkBox5.Checked  then begin streamIdx[0] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //wav
     if checkBox40.Checked then begin streamIdx[1] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //PS
     if checkBox4.Checked  then begin streamIdx[2] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //angle PS
     if checkBox41.Checked then begin streamIdx[3] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //sPS
     if checkBox42.Checked then begin streamIdx[4] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //cPS
     if checkBox43.Checked then begin streamIdx[5] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //vPS
     if checkBox44.Checked then begin streamIdx[6] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //mel sPS
     if checkBox45.Checked then begin streamIdx[7] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //PC
     if checkBox46.Checked then begin streamIdx[8] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //cPC
     if checkBox47.Checked then begin streamIdx[9] :=nbrOfStreams; inc(nbrOfStreams,1) end;              //vPC
     if checkBox48.Checked then begin streamIdx[10]:=nbrOfStreams; inc(nbrOfStreams,1) end;              //mel PC
     if checkBox49.Checked and checkBox15.Checked then //49: multimean cPS output, 15: cepstrum analysis                                                //mmcPS; f1.check15 = f1/analysis/PC; check49 = f1/output/multimean PS
      for i:=1 to NbrOfMultiMean do
        begin streamIdx[10+i]:=nbrOfStreams; inc(nbrOfStreams) end;
     if nbrOfStreams=0 then  //11012025
      begin
       showMessage('There was no out stream chosen, so the PC out will be arbitrary chosen.'#13'You can change it after unlocking the output settings');
       form2.CheckBox41.Checked:=true; //10012025
      end;
     form2.Edit3.Text:=intTostr(nbrOfStreams);
     setLength(outputRecord.streamArray,nbrOfStreams,count div 2+1);     //allocate memory to the stream array
     outPutRecordInit(outputRecord,nbrOfStreams,count div 2+1);
     setLength(tmpOutputRecord.streamArray,nbrOfStreams,count div 2+1);
     setLength(streamNames,nbrOfStreams);
     result:=AnalysisParamRegister(firstCall);                                     //1-th and 2-nd records: save parameters of analysis (zapis rekordu parametrów), save cathegory names (zapis nazw zmiennych kategorialnych)
     with outputRecord do //..............Stream names and graphics data
          //  1                                      2                 3                        4                   5   6               7                    8                    9   10               11               12                          13                   14                    15                16
     begin//streamsDescr(caption:shortString;const stand:boolean;var stream:TresArray; const  panelNbr:byte; const xSc,ySc:word;const color:longint; const decimals:byte; const Half,rev:boolean; var ic:byte; var tmpOutRecStream:TresArray; const check:TcheckBox; out newCaption:shortString;RigidChecksStates,weakChecksStates:word);
      if TryStrToInt(form2.Label63.caption,i) then out_sliceNbr:=i  //number of slices writed into 3-th record
      else out_sliceNbr:=0;
      phon:=char(radioGroup4.ItemIndex);                           //state of radio for CCR bundle writed into  3-th record
      ic:=0;
      if checkBox5.Checked  then    //wav c[0], d[0]
       begin
        streamsDescr(checkBox5.Caption,checkbox29.Checked,streamArray[streamIdx[0]],2,count-1,high(smallInt)-128,streamsGraphColors[0],panel2Decimals,false,false,ic,tmpOutputRecord.streamArray[streamIdx[0]],form2.CheckBox31,newCaption,c[0],d[0]);  //wav  high(smallInt)-128 to prevent NAN value for ysc in outputRecord
        checkBox5.Caption:=newCaption;
       end;
      if checkBox40.Checked then    //PS c[2], d[2]
       begin        //  1                     2                 3                    4  5   6               7           8   9   10    11        12                                  13                   14
        streamsDescr(checkBox40.Caption,checkbox30.Checked,streamArray[streamIdx[1]],3,cp,PSrange,streamsGraphColors[1],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[1]],form2.CheckBox32,newCaption,c[2],d[2]);      //PS
        checkBox40.Caption:=newCaption;
       end;
      if checkBox4.Checked  then    //aPS 0
       begin        //  1               2     3                        4  5 6 7                     8   9   10    11 12                                        13                   14
        streamsDescr(checkBox4.Caption,false,streamArray[streamIdx[2]],5,cp,3,streamsGraphColors[2],3,false,false,ic,tmpOutputRecord.streamArray[streamIdx[2]],form2.CheckBox37,newCaption,0,0);            //angle PS
        checkBox4.Caption:=newCaption;
       end;
      if checkBox41.Checked then    //sPS  c[3], d[3]
       begin
        streamsDescr(checkBox41.Caption,checkbox31.Checked,streamArray[streamIdx[3]],3,cp,PSrange,streamsGraphColors[3],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[3]],form2.CheckBox33,newCaption,c[3],d[3]);      //sPS
        checkBox41.Caption:=newCaption;
       end;
      if checkBox42.Checked then    //cPS  c[6], d[6]
       begin
        streamsDescr(checkBox42.Caption,checkbox32.Checked,streamArray[streamIdx[4]],3,cp,PSrange,streamsGraphColors[4],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[4]],form2.CheckBox36,newCaption,c[6],d[6]);      //cPS
        checkBox42.Caption:=newCaption;
       end;
      if checkBox43.Checked then    //vPS   c[5], d[5]
       begin
        streamsDescr(checkBox43.Caption,checkbox33.Checked,streamArray[streamIdx[5]],3,cp,PSrange,streamsGraphColors[5],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[5]],form2.CheckBox35,newCaption,c[5],d[5]);      //vPS
        checkBox43.Caption:=newCaption;
       end;
      if checkBox44.Checked then    //msPS  c[4], d[4]
       begin
        streamsDescr(checkBox44.Caption,checkbox34.Checked,streamArray[streamIdx[6]],3,cp,PSrange,streamsGraphColors[6],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[6]],form2.CheckBox34,newCaption,c[4],d[4]);      //mel sPS
        checkBox44.Caption:=newCaption;
       end;
      if checkBox45.Checked then    //PC  c[7], d[7]
       begin
        streamsDescr(checkBox45.Caption,checkbox35.Checked,streamArray[streamIdx[7]],4,cp,PCrange,streamsGraphColors[7],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[7]],form2.CheckBox41,newCaption,c[7],d[7]);      //PC
        checkBox45.Caption:=newCaption;
       end;
      if checkBox46.Checked then    //cPC  c[10], d[10]
       begin
        streamsDescr(checkBox46.Caption,checkbox36.Checked,streamArray[streamIdx[8]],4,cp,PCrange,streamsGraphColors[8],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[8]],form2.CheckBox44,newCaption,c[10],d[10]);    //cPC
        checkBox46.Caption:=newCaption;
       end;
      if checkBox47.Checked then    //vPC  c[9], d[9]
       begin
        streamsDescr(checkBox47.Caption,checkbox37.Checked,streamArray[streamIdx[9]],4,cp,PCrange,streamsGraphColors[9],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[9]],form2.CheckBox43,newCaption,c[9],d[9]);      //vPC
        checkBox47.Caption:=newCaption;
       end;
      if checkBox48.Checked then    //mPC  c[8], d[8]
       begin
        streamsDescr(checkBox48.Caption,checkbox38.Checked,streamArray[streamIdx[10]],4,cp,PCrange,streamsGraphColors[10],0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[10]],form2.CheckBox42,newCaption,c[8],d[8]);   //mel PC
        checkBox48.Caption:=newCaption;
       end;
      if checkBox49.Checked and checkBox15.Checked then  //mmcPS c[11], d[11]
       begin
        for i:=1 to NbrOfMultiMean do
         streamsDescr('11. Multi Mean (mm'+radiogroup4.Items[radiogroup4.itemIndex]+')_'+intTostr(10+i),{checkbox39.Checked}bundleStand,streamArray[streamIdx[10+i]],bundlePanel,cp,bundleRange,bundleColor,0,false,false,ic,tmpOutputRecord.streamArray[streamIdx[10+i]],form2.CheckBox45,newCaption,c[11],d[11]);
        checkBox49.Caption:='11. Multi Mean (mm'+radiogroup4.Items[radiogroup4.itemIndex]+')';
       end;
     end;{with outputRecord}
    if ic<>nbrOfStreams then showMessage('[WhatToSave], Error: Strings counters differ, nbrOfStreams='+intTostr(nbrOfStreams)+' but ic='+intToStr(ic));
   end;{with Form1}
  except
   showMessage('Some error occured in the proc. "WhatToSave" part 2.');
  end;
  try //Part 3.
   outRecordToFile(2);                       //3-rd record; save streams names (zapis rekordu nazw strumieni)
   outputRecord:=tmpOutputRecord;            //load streams graphs parameters
   try   //part 3.1.
   F0PlotDescr(outputRecord,F0PanelDecHalfRev,3,true,true,form2.panel1.Width div T0dashLength,round(1000*count/(2*rate)));
   // F0PlotDescr(var outputRecord:ToutputRecord;var F0PanelDecHalfRev:TPanelDecHalfRev;const decimals:byte; const Half,rev:boolean; const xRange,yRange:word);
    result:=filePos(OutPutRecordFile);       //debug prp
   outRecordToFile(3);                       //4-th record; save streams graphs parameters
    result:=filePos(OutPutRecordFile);       //debug prp
   saveCathSets;                             //5-th record; save set of cathegory values
    result:=filePos(OutPutRecordFile);       //debug prp
   SaveMultiMeanList;                        //6-th record; save averaging periods list
   except
    showMessage('Some error occured in the proc. "WhatToSave" part 3.1.');
   end;
    result:=filePos(OutPutRecordFile);       //debug prp
   try //part 3.2.
    FileNameEncode(waveFilePath);             //7-th record
   except
    showMessage('Some error occured in the proc. "WhatToSave" part 3.2.');
   end;
   result:=filePos(OutPutRecordFile);        //debug prp
   FileNameEncode(cathFilePath);             //8-th record
   result:=filePos(OutPutRecordFile);        //debug prp
  except
   showMessage('Some error occured in the proc. "WhatToSave" part 3.');
  end;
 End; {WhatToSave}

 procedure realFFT(var xr,yi:array of double);
 //for real data only!
  var i:word;
  begin
   for i:=0 to count-1 do yi[i]:=0;
   rfft_calc(index_mix,maxpower,sinar,cosar,xr,yi,count);
   for i:=0 to count-1 do xr[i]:=xr[i]/count;
  end;{realFFT}

 function writePathsToReport:boolean;
  begin
   try
     writeln(reportFile,'Report file path:');
     writeln(reportFile,'  ',ReportFilePath);
     Writeln(reportFile,'Input files paths:');
     Writeln(reportFile,'  ',waveFilePath);
     Writeln(reportFile,'  ',cathFilePath);
     writeln(reportFile,'Output files paths:');
     writeln(reportFile,'  ',OutRecordFilePath);
     Writeln(reportFile,'  ',GaussSearchFilePath);
     Writeln(reportFile,'Cathegories names:');
     Writeln(reportFile,'  ',form1.edit3.Text);
     Writeln(reportFile,'  ',form1.edit4.Text);
     Writeln(reportFile,'  ',form1.edit6.Text);
     Writeln(reportFile,'  ',form1.edit7.Text);
     writeln(ReportFile,flush(ReportFile));
     writePathsToReport:=true;
    except
     writePathsToReport:=false
    end;
  end;

 procedure InitWrite;
  var s:shortString;
   Begin
    try
     assignFile(initFile,InitDir);
     Rewrite(initFile);
     Writeln(initFile,waveFilePath);
     writeln(initFile,OutRecordFilePath);
     writeln(initFile,ReportFilePath);
     Writeln(initFile,GaussSearchFilePath);
     Writeln(initFile,cathFilePath);
     Writeln(initFile,form2.edit8.Text);
     Writeln(initFile,form1.edit3.Text);  //cathegories names
     Writeln(initFile,form1.edit4.Text);
     Writeln(initFile,form1.edit6.Text);
     Writeln(initFile,form1.edit7.Text);
     Writeln(initFile,allNormChecksStatesCode,' ', allOutChecksStatesCode,' ',frameNbr);
     CloseFile(initFile);
    except
     s:='File "'+initDir+'"';
     case TtextRec(initFile).mode of
      fmClosed:s:=s+' was closed';
      fmInput :s:=s+' was opened for reading (Reset)';
      fmOutPut:s:=s+' was opened for down writing';
      fmInOut :s:=s+' was opened for writing down, or appending or for reading';
      else     s:=s+' was in an unknown state';
     end; {case}
     showMessage('There was something wrong with writing initial settings, check the "'+InitDir+
     '" file (open, inspect and save, resaving helps, may be the file was corrupted in some way or had been'+
     ' already opened by some other program), or delete it'#13#10'Turn to the author if problem will repeat'#13#13+s);
    end;
   End;{InitWrite}

 procedure InitRead;
  var s:shortstring;
   Begin
    programDir:=ExtractFileDir(application.ExeName);//programDir:=getCurrentDir;
    InitDir:=programDir+'\SpectrInit.txt';
    if fileExists(InitDir) then
     begin
      assignFile(initFile,InitDir);
      reset(initFile);
      if fileSize(initFile)>0 then
      try
       readln(initFile,waveFilePath);
       readln(initFile,OutRecordFilePath);
       readln(initFile,ReportFilePath);
       readln(initFile,GaussSearchFilePath);
       readln(initFile,cathFilePath);
       readln(initFile,s);
       with form1 do
        begin
         readln(initFile,cathNameArr[1]); edit3.Text:=cathNameArr[1];
         readln(initFile,cathNameArr[2]); edit4.Text:=cathNameArr[2];
         readln(initFile,cathNameArr[3]); edit6.Text:=cathNameArr[3];
         readln(initFile,cathNameArr[4]); edit7.Text:=cathNameArr[4];
        end;{with form1, cath names}
       with form2 do
       begin
        label64.caption:=cathNameArr[1];
        label66.caption:=cathNameArr[2];
        label70.caption:=cathNameArr[3];
        label5.caption:=cathNameArr[4];
       end;{with form2}
       setLength(frameNbrArr,1);
       Readln(initFile,allNormChecksStatesCode, allOutChecksStatesCode,frameNbr);  //Normalise and Out checkboxes states codes
       if allOutChecksStatesCode=0 then
        begin
         showMessage('The code of out checkbox states is =0; it must point at least to one output stream'#13#10'Now we take  change this situation by pointing to the PC stream');
         allOutChecksStatesCode:=1 shl 8; //=PC
        end;
       OutCheckStatesRestore;                                           //restore last Out chechbox settings
       NormCheckStatesRestore;                                        //restore last Standardise chechbox settings
       form2.edit24.Text:=intToStr(frameNbr);
       CloseFile(initFile);

       form2.edit8.Text:=s;
      except
       s:='The file "'+initDir+'"';
       case TtextRec(initFile).mode of
        fmClosed:s:=s+' was closed';
        fmInput :s:=s+' was opened for reading (Reset)';
        fmOutPut:s:=s+' was opened for down writing';
        fmInOut :s:=s+' was opened for writing down, or appending or for reading';
        else     s:=s+' was in an unknown state';
       end; {case}
       showMessage('There was something wrong with reading initial settings, check the "'+InitDir+
       '" file, or delete it'#13#10'Turn to the author if problem will repeat'#13#13+s);
      end {try}
      else CloseFile(initFile);{if fileSize(initFile)>0}
     end
    else cathFilePath:=dataDir+'\*.cath';{if fileExists(InitDir)}
   End; {InitRead}

procedure labelsClear(labelSet:TlabelSet);
var ctrl: TLabel;  i,j:Integer;
Begin
 with form1 do
  for i := 0 to Panel1.ControlCount-1 do
   if panel1.Controls[i] is Tlabel then
    begin
     ctrl :=Form1.panel1.controls[i] as Tlabel;
     with ctrl do
      if TryStrToInt(Copy(Name,Length(Name)-1,2),j) then
       if j in labelSet then ctrl.caption:='xxxxxx';
    end;
End; {labelsClear}

procedure waveInput(var waveFile:TSmallIntFile;const dataBlockLength:longWord; out m:dWord; out signalStdev:extended);
{
 ładuje dane z dysku bez kreślenia oscylogramu
}
 var i,k,ti : longWord;
          j : smallInt;
 sum, sqSum : int64;
       mean : extended;
 procedure Progress;
  Begin
   with form1 do
    begin
     k:=Round(100*(i/m));
     Label91.Caption:=floatToStr(k)+'%';
     ProgressBar1.Position:=k;
     application.ProcessMessages;
    end;
  End;{progress}

  begin //--------------------------------waveInput-------------------------
   form1.Button3.Enabled:=false;//zablokować możliwość ponownego uruchomienia programu przed zakończeniem czytania danych
   screen.Cursor:=-2;  sum:=0; sqSum:=0;
   form1.StatusBar1.Panels.Items[0].Text:='Data loading from file "'+waveFilePath+'" to memory';
   application.processmessages;
   reset(waveFile);
   i:=fileSize(waveFile);
   seek(waveFile,22);
   i:=0;
   m:=(dataBlockLength+1) div 2-1;
   ti:=2 shl (Round(Ln((m/100))/ln(2))-1);                            //for progress bar incrementations
   breakLoad:=False;
   with form1 do
    begin
     while (not (eof(waveFile) or (i>m))) and not BreakLoad do
      Begin
       inc(i);
       read(waveFile,j);
       speech[i]:=j;
       sum:=sum+j; sqSum:=sqSum+j*j;
       if i mod ti=0 then Progress;   //increase Progress Bar
      End;{while}
     mean:=sum/i; signalStDev:=sqSum/i;        form1.label68.caption:=floatToStr(mean);
     signalStDev:=sqrt(signalStDev-mean*mean); form1.label70.caption:=floatToStr(signalStDev);
     Progress;
    end;{with form1}
    beep;
   application.ProcessMessages;
   if eof(waveFile) then showMessage('End of file encountered!')
   else showMessage('End of the file was not reached!');
   showMessage('End of the file reading! It was read '+intToStr(i)+' numbers.');
   m:=i;
   i:=high(speech);                   //for debug
   for i:=m+1 to i do speech[i]:=0;   //fill rest of the list with 0's
   close(waveFile);
   Form1.StatusBar1.Panels.Items[0].Text:='';
   application.processMessages;
   screen.Cursor:=0;
  end;{waveInput}

  procedure showWaveHead(canvas:tcanvas;var waveFile:byteFile;  waveFilePath:string; out RIFF:string; out fileLength:longWord;out Wave,fmt:string;
  out lengthOfFmtData:word;out PCM,MonoSter:byte;out SampleRate:double; out blockAlign:word;out BACBS,bits_sample:byte;
  out wave_data:string; out dataBlockLength:longWord);
  var
      arr4 : array[1..4] of byte;
      arr2 : array[1..2] of byte;
         s : string[4];

   function strRedout(lab:tlabel; k:byte):string;
    var i,j:byte;
     Begin
      s[0]:=char(k);
      for i:=1 to k do
       begin
        read(waveFile,j);
        s[i]:=char(j)
       end;
      lab.caption:=s;
      strRedout:=s;
     End; {strRedout}

   function nbr4Redout(lab:tlabel):longWord;
    var i:byte;
     Begin
      for i:=1 to 4 do
       begin
        read(waveFile,arr4[i]);
       end;
      result:=longWord(arr4);
      lab.caption:=intToStr(result);
     End; {nbr4Redout}

    function nbr2Redout(lab:tlabel):word;
    var i:byte;
     Begin
      for i:=1 to 2 do
       begin
        read(waveFile,arr2[i]);
       end;
      nbr2Redout:=Word(arr2);
      lab.caption:=intToStr(result);
     End; {nbr2Redout}

    Begin //--------------------------showWaveHead-------------------------------------
     if not fileExists(waveFilePath) then
      begin
       showMessage('File "' +waveFilePath+'" does not exist');
       exit
      end
     else
      with form1 do
       begin
       Label11.Caption:='WAVE file "' +waveFilePath+'" parameters:';
       label11.Hint:=label11.Hint+' '+label11.Caption;    //26012025
       end;
     AssignFile(waveFile,waveFilePath);
     reset(waveFile);
     with form1 do
      begin
       label12.caption:='RIFF  4';                                              RIFF:=strRedout(label25,4);
       label13.caption:='file length  4';                                fileLength:=nbr4Redout(label26);
       label14.caption:='WAWE  4';                                              Wave:=strRedout(label27,4);
       label15.caption:='fmt  4';                                                fmt:=strRedout(label28,4);
       label16.caption:='0x00000010 lengt of fmt data  4';          lengthOfFmtData:=nbr4Redout(label29);
       label17.caption:='0x0001 Format tag: 1=PCM  2';                          PCM:=nbr2Redout(label30);
       label18.caption:='channels Channels: 1=mono, 2=stereo  2';          MonoSter:=nbr2Redout(label31);
       label19.caption:='sample rate Samples per s  4';                  SampleRate:=nbr4Redout(label32);
       label20.caption:='bytes/s sample rate*block align  4';            blockAlign:=nbr4Redout(label33);
       label21.caption:='block align channels*bits/sample/8  2';              BACBS:=nbr2Redout(label34);
       label22.caption:='bits/sample 8 or 16  2';                       bits_sample:=nbr2Redout(label35);
       label23.caption:='data  4';                                        wave_data:=strRedout(label36,4);
       label24.caption:='length of the data block  4';
       dataBlockLength:=nbr4Redout(label37);  //liczba bajtów, liczenie zaczyna się od zera!
      end;{with}
    End;{showWaveHead}

 procedure showWaveHeadRecord(canvas:tcanvas;var waveFile:TSmallIntFile; out WaveCaption:TWaveCaption);
  var i:byte;
  waveCaptionArray:TwaveCaptionArray;
  Begin
    if not fileExists(waveFilePath) then
      begin
       showMessage('Can not show Wave Head because file "' +waveFilePath+'" does not exist; turn to the author...');
       exit
      end
    else
     with form1 do
      begin
      Label11.Caption:='WAVE file "' +waveFilePath+'" parameters:';
      label11.Hint:=label11.Hint+' '+label11.Caption;    //26012025
      end;
    AssignFile(waveFile,waveFilePath);
    reset(waveFile);
    for i:=0 to 21 do read(waveFile,waveCaptionArray[i]);
    WaveCaption:=TWaveCaption(waveCaptionArray);
     with form1,WaveCaption do
      begin
       label12.caption:='RIFF  4';                                              label25.Caption:=RIFF;
       label13.caption:='file length  4';                                       label26.Caption:=intToStr(fileLength);
       label14.caption:='WAWE  4';                                              label27.Caption:=Wave;
       label15.caption:='fmt  4';                                               label28.Caption:=fmt;
       label16.caption:='0x00000010 lengt of fmt data  4';                      label29.Caption:=intToStr(lengthOfFmtData);
       label17.caption:='0x0001 Format tag: 1=PCM  2';                          label30.Caption:=intToStr(PCM);
       label18.caption:='channels Channels: 1=mono, 2=stereo  2';               label31.Caption:=intToStr(MonoSter);
       label19.caption:='sample rate Samples per s  4';                         label32.Caption:=intToStr(SampleRate);
       label20.caption:='bytes/s sample rate*block align  4';                   label33.Caption:=intToStr(blockAlign);
       label21.caption:='block align channels*bits/sample/8  2';                label34.Caption:=intToStr(BACBS);
       label22.caption:='bits/sample 8 or 16  2';                               label35.Caption:=intToStr(bits_sample);
       label23.caption:='data  4';                                              label36.Caption:=wave_data;
       label24.caption:='length of the data block  4';                          label37.Caption:=intToStr(dataBlockLength);  //liczba bajtów, liczenie zaczyna się od zera!
       edit1.Text:=label32.Caption;
      end;{with}
  End;{showWaveHeadRecord}

 procedure MelScale;
  var k:word;
  wsp,fk:double;
  Begin
   wsp:=(log10(1+rate/(2*melBasis)))/cp;
   for k:=1 to cp do
    begin
     fk:=melBasis*(power(10,k*wsp)-1);
     melIdx[k]:=round(int(fk/df));
     melFreq[k]:=fk;
    end;{for}
  End;

procedure fft_par(edit,edit2:Tedit);
  var  i:Word;
{
--------- rFFT parameters----------------
}
 Begin
  PSrange:=80; PSrange0:=80; form2.button19.Caption:= 'Reset '+intToStr(PSrange0);// PCrange:=1000; PCrange0:=100;
  if form1.Edit24.Enabled then frameNbr:=StrToInt(Form1.Edit24.Text);
  frameNbr0:=frameNbr;
  i:=count;
  count:=strToInt(Edit.Text);   //strToInt(form2.Edit5.Text) 11122023
  count:=round(power(2,round(ln(count)/ln(2))));   //27092023
  edit.Text:=intToStr(count);  edit2.Text:=edit.Text;
  manager:='R';//FramesRepaint(count_cp);
  if i<>count then showMessage('You have changed windows width, may be, windows jump should be changed. Now it is ='+
   intToStr(jumpNbrSamples)+' points, while windows width is='+intToStr(count)+' points'+#13#10'Check also lifter '+
   'treshold point, it is now='+intToStr(cpstrPoint)+' i.e. '+floatToStrF(1000*cpstrPoint/rate,ffFixed,3,3)+
   'ms. Change it, if necessary, with "'+form2.Label71.Caption+'".');
  if count<cpstrPoint then showMessage('There is no possibility to evaluate the F0 frequency due to setting of lifter'+
   ' treshold at '+intToStr(cpstrPoint)+' point, i.e. '+floatTostrF(1000*cpstrPoint/rate,ffFixed,3,3)+' ms when rate='+
   intToStr(round(rate))+'Hz'#13#10'You can change the treshold with the "'+form2.label71.caption+
   '" edit window; you should divide it by sampling rate to obtain the liftering treshold time');
  RamAllocate;
  maxPower:=high(yZero);
  for i:=0 to maxpower do yZero[i]:=0;
  y0(Yzero,count);                                 //wyzeruj tablicę Yzero
  df:=rate/count;
  dOm:=2*pi/count; dOmKw:=sqr(dOm);
  SinCosArrays(cosar,sinar,count);                 //tablice sinusów i cosinusów
  power2(maxpower,count);
  ind_mix_Arr(index_mix,count);
  gaussScaler:=strToInt(form2.Edit13.Text);//200;//count;
  gaussStdev:=strToInt(form2.Edit4.Text)/gaussScaler;
  winNbr:=form1.RadioGroup7.ItemIndex;            //tablica wag, 25.07.05
  rectWinFill:=strTofloat(form1.Edit15.text);
  rectFill:=count div 2-1; form2.Edit7.Text:=intToStr(rectFill);
  half_win:=form1.checkBox24.Checked;
  WindowsWeights(winNbr,gaussStDev,windowWeights,WeightMean,count);   //-----------------------------------tabele wag okiennych-------------------
  melScale;
  T0Fixed:=cpstrPoint;
  if form2.CheckBox95.Checked then cpstrVizXrange:=cpstrPoint+1  //wide cepstra
  else cpstrVizXrange:=count_cp;
 End;{fft_par}

 procedure osc_par(const rate:word);
 {
 ----------stale parametry wykresu oscylogramu-------------
 }
 begin
  jumpNbrSamples:=round(jump*(rate/1000));         {tryb synchr., ogran. }
  form1.Edit2.Text:=intToStr(jumpNbrSamples); form2.Edit1.Text:=form1.Edit2.Text;
 end;{osc_par}

 procedure saveSample;
 //-------zapis wybranych próbek wraz z wynikami analiz do pliku tekstowego
 var i,j:word;   s:shortString;
  Begin
   if not saveSlide then exit;
   if not ReportSave then
    begin
     showMessage('The slide can not be saved because you have chosen "Not save report"');
     exit
    end;
   if form2.RadioGroup7.Items[form2.RadioGroup7.itemIndex]='&Gauss' then
    s:='; Gauss standard deviation='+floatToStr(strToInt(form2.edit4.text)/strToint(form2.Edit13.Text))
   else s:='';
   writeln(ReportFile,#13#10'Slice number: ',outPutrecord.out_sliceNbr,'; weighting window: ',
    form2.RadioGroup7.Items[form2.RadioGroup7.itemIndex],'; points: ',form2.Edit5.Text,s);
   writeln(ReportFile,#13#10'T0 idx                              ',T0:12,
                      #13#10'Cepstrum amplitude at T0 idx        ',cpstrT0:12:4,
                      #13#10'Dynamics of deconvoluted spectrum   ',vPSstDev:12:4);
   //with stepOutrecord do
    writeln(ReportFile,'Cath 1, i.e. ',cathNameArr[1],': "',stepOutrecord.phon,'", Cath 2, i.e. ',cathNameArr[2],': "',stepOutrecord.person,'", Cath 3, i.e. ',cathNameArr[3],': "',stepOutrecord.gender,'", Cath 4, i.e. ',cathNameArr[4],': "',stepOutrecord.age,'".');
   Writeln(reportFile,#13#10'The vectors components are written in columns separated with tabs'#13#10);
   write(ReportFile,'Nr'#9'Signal':12,#9'W.Signal':12,#9'PS':12,#9'angle':12,#9'vPS':12,#9'cPS':12,#9'sPS':12,#9'msPS':12,#9'PC':12,#9'vPC':12,#9'cPC':12,#9'mPC':12,#9);
   if form1.CheckBox49.Checked and  form1.checkBox15.Checked then
    for i:=0 to NbrOfMultiMean do write(ReportFile,frameNbrArr[i]:12,#9);
  writeln(ReportFile);
  for i:=0 to count-1 do
   //with stepOutrecord do
    begin
      write(ReportFile,i,#9,stepOutrecord.signal[i]:12,#9,stepOutrecord.weighedSignal[i]:12,#9,
       stepOutrecord.powerSpectr[i]:12,#9,stepOutrecord.slide_angle[i]:12,#9,stepOutrecord.vPSarr[i]:12,#9,stepOutrecord.cPSarr[0,i]:12,#9,stepOutrecord.smoothedSpectr[i]:12,#9,stepOutrecord.melSmoothSpectr[i]:12,#9,
       stepOutrecord.powerCepstr[i]:12,#9,stepOutrecord.vPCarr[i]:12,#9,stepOutrecord.cPCarr[i]:12,#9,stepOutrecord.melCepstr[i]:12,#9);

        stepOutrecord.signal[i]:=0; stepOutrecord.weighedSignal[i]:=0; stepOutrecord.powerSpectr[i]:=0; stepOutrecord.slide_angle[i]:=0; stepOutrecord.vPSarr[i]:=0; stepOutrecord.cPSarr[0,i]:=0;
        stepOutrecord.smoothedSpectr[i]:=0; stepOutrecord.melSmoothSpectr[i]:=0; stepOutrecord.powerCepstr[i]:=0; stepOutrecord.vPCarr[i]:=0; stepOutrecord.cPCarr[i]:=0; stepOutrecord.melCepstr[i]:=0;

      if form1.CheckBox49.Checked and  form1.checkBox15.Checked then
      for j:=0 to NbrOfMultiMean do
       begin
        write(ReportFile,stepOutrecord.cPSarr[j,i]:12,#9);
        stepOutrecord.cPSarr[j,i]:=0;
       end;
      writeln(ReportFile);
    end;
   writeln(ReportFile,'========================================================================================'#13#10);
   flush(ReportFile);
   saveSlide:=false;
  End;{saveSample}

 procedure saveHistory(sliceNbr:longInt);
 // saves reHistoryArr to ReportFile
  var i,j,k:word;
  Begin
   if not reportSave then
    begin
     showMessage('History of averaging process can not be saved due to that you have chosen "Not save report".');
     exit
    end;
   writeln(ReportFile,#13#10'================================================================================',#9);
   writeln(ReportFile,'History of PC averaging over time, showed here as "cPC", count=',count,', slice nuber=',sliceNbr,'. Debug purpose, for convenient read in excel.');
   writeln(ReportFile,'i':4,#9'   j':4,#9' means terms vectors',#9);
   for i:=0 to NbrOfMultiMean do
    begin
     writeln(ReportFile,i,'-th mean, ',frameNbrArr[i],' time-points;',' ring buffer write-point=',
      ringBuffChangePointArr[i],' (index counts from 0);',' slice nuber=',sliceNbr,#9);
     for j:=0 to frameNbrArr[i]-1 do
      begin
       write(ReportFile,i:4,#9,j:4,#9);
       for k:=0 to count div 2 do
        write(ReportFile,reHistoryArr[i,j,k]:8:4,#9);
       writeln(ReportFile);
      end;
     write(ReportFile,'Mean   ',#9#9);
     for k:=0 to count div 2 do
      write(ReportFile,reMeanVectorArr[i,k]:8:3,#9);
     writeln(ReportFile);
     flush(ReportFile);
    end;{for i}
  End;{saveHistory}

 procedure ToStepOutRecord(var input:TdbArr; out outputer:Array of single);
 //wyprowadza przekroj do stepOutputRecord
  var i:word;
  Begin
   if not saveSlide then exit;
   for i:=0 to count-1 do
    outputer[i]:=input[i];
  End;{ToStepOutRecord}

  procedure ComputeFilter;
 (*
 Obliczyć tablicę filtru
 Wywoływać PO wczytaniu nagłówka danych (ze względu na parametr rate)
 reguła: Curve equation: y(ln(f))=10 exp{-sqr(ln((i*rate/count)/fc))/v}
 *)
 var
   i,fc : integer;//word;
  r1,r2 : double;
 Begin
  form2.label18.Caption:='Filters shape'; label18Caption:=form2.label18.Caption;
  i:=high(filter);
  r2:=sqr(ln(4000/300)/ln(10));       //Gauss curve variance = 1.26548716          here was analyfilter[0]:=1;
  case form1.radiogroup2.ItemIndex of
   0: begin    //none
       for i:=0 to count div 2 do filter[i]:=1;
       filterDraw(filter,form1,form1.panel4,form1.label57,clBlack,f1wspx4,f1wspy4,f1centr4);   //procedure FilterDraw(var filter:array of double;form:tform;panel:tpanel;label0:Tlabel);
       filterDraw(filter,form2,form2.panel6,form2.label18,clBlack,wspx6,wspy6,centr6);
       exit;
      end;
   1:fc:= 300; //300 Hz
   2:fc:=1000; //1000 Hz
   3:fc:=4000; //4000Hz
   4:begin    //summ
      for i:=1 to count div 2 do
       begin
       filter[i]:=sqr((exp(-sqr(ln(i)+ln(df)-ln(300))/r2)+
                   exp(-sqr(ln(i)+ln(df)-ln(1000))/r2)+
                   exp(-sqr(ln(i)+ln(df)-ln(4000))/r2))/1.5651565);
       end;{for}
      filterDraw(filter,form1,form1.panel4,form1.label57,clBlack,f1wspx4,f1wspy4,f1centr4);   //procedure FilterDraw(var filter:array of double;form:tform;panel:tpanel;label0:Tlabel);
      filterDraw(filter,form2,form2.panel6,form2.label18,clBlack,wspx6,wspy6,centr6);
      exit;
     end;
  end;{case}
  r1:=ln(df)-ln(fc);                 //df=rate/count, przyrost częstotliwościzainicjować po wczytaniu nagłówka danych!
  for i:=1 to count div 2 do filter[i]:=Sqr(exp(-sqr(ln(i)+r1)/r2));
  filterDraw(filter,form1,form1.panel4,form1.label57,clBlack,f1wspx4,f1wspy4,f1centr4);   //procedure FilterDraw(var filter:array of double;form:tform;panel:tpanel;label0:Tlabel);
  filterDraw(filter,form2,form2.panel6,form2.label18,clBlack,wspx6,wspy6,centr6);
 End;{ComputeFilter}

procedure melTrans(var reIns:TdbArr);
 var i:word;
 tempAry:TdbArr;

 function extrapol(xr:TdbArr;fk:double;i:word):double;
  Begin
   result:=xr[2]-(xr[2]-xr[1])*(2*df-fk)/df
  End;

 function interpol(xr:TdbArr;fk:double;i:word):double;
  Begin
   result:=xr[i]+(xr[i+1]-xr[i])*(-i*df+fk)/df
  End;

 Begin
  setLength(tempAry,count);
  tempAry[0]:=reIns[0];
  for i:=1 to cp do
   begin
    if melfreq[i]<df then  tempAry[i]:=extrapol(reIns,melFreq[i],i)
    else
    if cp>=2 then tempAry[i]:=interPol(reIns,melFreq[i],melIdx[i]);
    tempAry[count-i]:=tempAry[i];
   end;
  reIns:=tempAry;
  setLength(tempAry,0);
 End;{melTrans}

 procedure AlignDrawing(const ArrX,ArrY:TdbArr;panel:Tpanel;const n:word;const wspx,wspy:double;const centr:integer;const chartColor:longint; const AlCheckBox:TcheckBox; var VizCheckBox:TcheckBox);
  var i:word; A,B:extended;   s:shortString;
  Begin if not form2.CheckBox1.Checked then exit;  //show graphs
   s:=vizCheckBox.caption;
   i:=pos('=',vizCheckBox.caption);
   if i>0 then delete(s,i-2,length(vizCheckBox.caption));
   vizCheckBox.caption:=s;

   if not alCheckBox.Checked then exit;

   LinReg(ArrX,ArrY,n,A,B);   //Linear regression coefficients
   if form2.checkBox98.Checked then A:=abs(A);
   for i:=0 to high(ArrX) do    //convert
    tmp_Virt_Vect[i]:=A*ArrX[i]+B;
    with form2 do
     begin
      SpcDraw(panel,canvas,tmp_Virt_Vect,wspx,wspy,centr,n,clear,chartColor,checkBox4.Checked);//Aligned drawing
     end;
   s:=' A='+floatToStrF(A,ffExponent,3,2)+' B='+floatToStrF(B,ffExponent,3,2);
   vizCheckBox.caption:=vizCheckBox.caption+s;
  End;{AlignDrawing}

 procedure InputPrepare(var annotation:boolean; const i:dword);
   {
   Prepares slide and performs diagnostic or testing transformations
   }
    var j:Word;  mean, stdev:extended;

    function diagnosticBox:boolean;

     function sinSumm(i:word):double;
      //computes summ of harmonics ; j - time, k - harmonics number; g1, g2 - gap
      var k:dword;
      Begin
       result:=0;
       for k:=1 to harmNbr do                                      //harmNbr - Harmonics number
        result:= result+sin(2*pi*(k*harmSpace+harmBiass)*i/rate);  //harmSpace - harmonics space (df)  harmBiass - 1.th harm. biass
       result:=round(result*30000/harmNbr);
      End;{sinSumm}

     var i,j,k:word;
     Begin
      result:=true;
      with form2 do
       if checkbox80.Checked then  //artificial signal, harmonics
        begin
         for j:=1 to count-1 do
          begin
           xr[j]:=sinsumm(j)
          end
        end
       else result:=false;
     End;{diagnosticBox}

     procedure normalize_slice;
      var j:word;
      begin
       meanAndStdDev(xr,mean,stdev);
       if stdev>0 then                                         
        for j:=0 to count-1 do xr[j]:=xr[j]/stdev
       else for j:=0 to count-1 do xr[j]:=0;
     end;{normalize_slice}

    Begin     //--------------------------InputPrepare--------------------------
     temp:=high(StepOutRecord.signal); j:=high(xr0);//debug
     ToStepOutRecord(xr,StepOutRecord.signal);   //slide of the original signal, xr is not modified here (slajd sygnału oryginalnego; xr nie jest tu modyfikowany)
     with form2 do
      begin
       diagnosticBox;
       if (checkbox82.checked) then normalize_slice;     //standaryzation of the xr (= ArrY )
       if checkbox7.Checked then  //===================show oscillogram of a portion=====================
        OscDraw(panel2,canvas,xr,wspx2,wspy2,centr2,count,true,clblue,i,annotation);
       for j:=0 to count-1 do begin xr0[j]:=xr[j]; xr[j]:=xr[j]*windowWeights[j] end;                     //----------weighting window
       if checkbox83.Checked  then normalize_slice; //----------Normalize weighed signal  this plot xr = ArrX
       if form2.CheckBox8.Checked  then   //wykres ważonego oscylogramu okienka  (ArrX)
        begin
         clear:=not checkbox7.checked;
        with form2 do// function *1E-4
         if not CheckBox82.Checked and CheckBox83.Checked and  CheckBox7.Checked  and CheckBox8.Checked then //10122023
          OscDraw(panel2,canvas,xr,wspx2,10000*wspy2,centr2,count,clear,clwhite,i,annotation)   //ważony oscylogram normalizowanego sygnału  {1.5*totalSignalStDev}(high(smallInt)/   this xr=ArrX
         else OscDraw(panel2,canvas,xr,wspx2,wspy2,centr2,count,clear,clwhite,i,annotation);   //ważony oscylogram nienormalizowanego sygnału ważonego
        end;
        if form2.checkBox18.Checked then
         begin
          clear:=not checkbox7.checked and not checkbox8.checked;
         end;
        AlignDrawing(xr,xr0,panel2,count-1,wspx2,wspy2,centr2,clRed,form2.checkBox18,form2.checkBox8);     //here xr=ArrX, xr0=ArrY
      end;{with form2}
      ToStepOutRecord(xr,StepOutRecord.WeighedSignal);   //slide of the weighted signal, xr is not modified here (slajd sygnału ważonego; xr nie jest tu modyfikowany)
      with outputRecord do
       begin
        stepOutRecord.phon:=phon;
        stepOutRecord.person:=person;
        stepOutRecord.age:=byte(age);
        stepOutRecord.gender:=gender;
       end;
     End;{InputPrepare}

 procedure Normalize(var v_v:array of double);
  var j:Integer;
   mean,StdDev,extemp : extended;
  Begin
    Begin
     meanAndStdDev(v_v,mean,stdDev);
     for j:=0 to high(v_v) do //count div 2 07112024
      begin
       if stdDev >0 then extemp:=(v_v[j]-mean)/stdDev else extemp:=0;
       v_v[j]:=exTemp
      end
    End
  End;{Normalize}

 procedure resultsOut(check57:boolean; var v_v:array of double; out outPut:array of single);
 //Zapisuje strumień do rekordu wyjściowego
  var j:Integer;
  Begin
   if not spcSave then exit;        //{2,save}  spcSave:=whereSave(OutRecordFilePath,'Save spectrum analysis results, into eg. "'+fileDir+'\'+FileName,'spc');  (from: OpenFiles, w. 2148 16122022)
   if not Check57 then exit;       //Check57: write down results at all? (czy wogóle zapisywać wyniki?)
    for j:=0 to count div 2 do
     outPut[j]:=v_v[j];
  End;{resultsOut}

 procedure PowerSpectrum;
 //xr         - input signal (real)
 //xr, yi     - fft transform  (even and odd)
 //virt_vect  - output, power spectrum [dcB|nepher] (even)
 //angle      - output, phase   (odd)
  var mean, stdev:extended; i:word;    chartColor:longint;
  Begin
   case form2.RadioGroup1.ItemIndex of   //fast/slow FFT/DCT
  0,1:  begin   //FFT
         for i:=0 to count-1 do yi[i]:=0;
         rfft_calc(index_mix,maxpower,sinar,cosar,xr,yi,count);     //dividing by count is carried out in the "modul" procedure
         chartColor:=clblue;
        end;
    2:  begin  //fast DCT
         for i:=0 to count-1 do tmpArr[i]:=xr[i];
         Fastdct(tmpArr,count);
         for i:=0 to count-1 do xr[i]:=tmpArr[i]*count;
         chartColor:=clBlue+100;
        end;
     3:  begin //slow DCT
          for i:=0 to count-1 do tmpArr[i]:=xr[i];
          slowdct(tmpArr,count);
          for i:=0 to count-1 do xr[i]:=tmpArr[i]*count;
          chartColor:=clBlue+200;
         end;
   end;
   streamsGraphColors[1]:=chartColor; streamsGraphColors[2]:=chartColor;  //kolor wykresu nie zależy od przydzielonego mu numeru strumienia
   modul(xr,yi,virt_vect,angle,count,form2.CheckBox3.Checked,false);    //xr, yi - data, not modified here! virt_vect, angle - results form2.CheckBox3.Checked - true nepher, false - decibel
   with form2 do
    begin
     if form1.CheckBox30.checked then Normalize(virt_vect);
     if checkBox9.Checked then SpcDraw(panel3,canvas,virt_vect,wspx3,wspy3,centr3,count_cp,true,streamsGraphColors[1],checkBox4.Checked); //the spectrum; plot (PS)
     if checkBox26.Checked then SpcDraw(panel5,canvas,angle,wspx5,wspy5,centr5,count_cp,true,streamsGraphColors[2],checkBox4.Checked);    //phase plot (aPS);check4 - "clip" for power spectrum
    end;{with}
   if form1.CheckBox40.Checked then   //PS to output
    resultsOut(form1.CheckBox57.checked,virt_vect,outputRecord.streamArray[streamIdx[1]]);
   if form1.CheckBox4.Checked then    //angle to output
    resultsOut({false,}form1.CheckBox57.checked,angle,outputRecord.streamArray[streamIdx[2]]);
   ToStepOutRecord(virt_vect,StepOutRecord.powerSpectr); //(virt_vect nie jest tu modyfikowany
   ToStepOutRecord(angle,StepOutRecord.slide_angle);
   application.ProcessMessages;
  End;{PowerSpectrum}

  function findT0(reins:array of double; const iw:dword):word;   // T0 time graph (wykres przebiegu T0 na górnym panelu)
   var i:word;
    max:double;

   Begin  //-------------------------findT0-----------------
    max:=0;  result:=cp;
    for i:=cpstrPoint to cp do
     begin
      if reIns[i]>max then
       begin
        max:=reins[i];
        result:=i;
       end;{if}
     end;{for}
     F0:=rate/result; OutputRecord.pF0:=F0;
    cpstrT0:=reIns[result];
    if not timeBack then //zapobiega określaniu T0Fix podczas uśredniania już na samym początku (03042014)
    if FixT0 then      //ustalanie T0Fixed zachodzi tylko dla pierwszego okna ważącego (a dokładniej - dla okna nr 0)
     begin
      T0Fixed:=result;
      fixT0:=false
     end;
    cpstrT0Fixed:=reIns[T0Fixed];//"cpstrT0Fixed" is a value in the current cepstrum at the point "T0Fixed" found for the Hamming window
    if form2.CheckBox1.Checked and not form2.CheckBox95.Checked then  //show graphs
     begin
      lifterLine(result,wspx4,wspy4,clPurple,not TimeBack,form2.panel4);
      if windowsSearching then lifterLine(T0Fixed,wspx4,wspy4,clgreen,not TimeBack,form2.panel4);
     end;{show graphs}
    application.ProcessMessages;
   End;{findT0}

  Procedure label53Caption;
    Begin
    if high(reIns)>2 then form2.label53.caption:=' PC[0]='+floatToStrF(reIns[0],ffGeneral,6,2)+'; PC[1]='+floatToStrF(reIns[1],ffGeneral,6,2)+'; PC[2]='+floatToStrF(reIns[2],ffGeneral,6,2)+'; PC[3]='+floatToStrF(reIns[3],ffGeneral,6,2)
     else
      if high(reIns)>1 then form2.label53.caption:=' PC[0]='+floatToStrF(reIns[0],ffGeneral,6,2)+'; PC[1]='+floatToStrF(reIns[1],ffGeneral,6,2)+'; PC[2]='+floatToStrF(reIns[2],ffGeneral,6,2)
      else
       if high(reIns)>0 then form2.label53.caption:=' PC[0]='+floatToStrF(reIns[0],ffGeneral,6,2)+'; PC[1]='+floatToStrF(reIns[1],ffGeneral,6,2)
       else form2.label53.caption:='Not approachable';
    End;{label53Caption}

  procedure PowerCepstrum(const iw:dword);
  //input - virt_vect (even)
  //output - reIns (even), imIns (zero), angle (zero) i.e. output is real and even
  var j:Word;   mean,stdev:extended;
  t1,t2:double;
  Begin //---------------------------------- POWER CEPSTRUM  --------------------------
 (*  if form2.CheckBox20.Checked then  //Normalize power spectrum  ? - only for control-diagnostic prp
    begin
     meanAndStdDev(virt_vect,mean,stdev);  //(tempVect,mean,stdDev);
     for j:=0 to count-1 do virt_vect[j]:=(virt_vect[j]-mean)/stdev;
    end;   *)
    t1:=high(reIns); t2:=high(imIns);    //debug prp
   for j:=0 to count-1 do
   try                                 //debug prp
    begin
     reIns[j]:=virt_vect[j]; ImIns[j]:=0;
    end;
    except
     showMessage('Program falled at the procedure "PowerCepstrum", at j='+intToStr(j));
    end;
   rfft_calc(index_mix,maxpower,sinar,cosar,reIns,ImIns,count);
   for j:=0 to count_cp-1 do
    begin
     t1:=reIns[j]; t2:=imIns[j];
    try
     angle[j]:=arctan(t2/t1);
    except
     angle[j]:=pi*sign(t1)/2
    end;
    end;{for}
   with form2 do
    begin
     if form1.CheckBox35.checked then Normalize(reIns);
     if checkBox14.Checked then SpcDraw(panel4,canvas,reIns,wspx4,wspy4,centr4,cpstrVizXrange,true,streamsGraphColors[7],checkBox5.Checked); //clBlue                                        //omit constant component in standardization (pominąć składową stałą w STANDARYZACJI)
     label53Caption;
     if checkBox29.Checked then SpcDraw(panel5,canvas,angle,wspx5,wspy5,centr5,count_cp,not checkbox26.Checked,streamsGraphColors[7]+10,checkBox5.Checked); //clBlue+10
    end;
   lifterLine(cpstrPoint,wspx4,wspy4,clWhite,not TimeBack,form2.panel4); //show lifter treshold line
   if form2.CheckBox66.Checked then T0:=FindT0(reIns,iw);               //find T0 and mark it with a line
   form2.Label51.Caption:=floatToStrF(1000*T0/rate,ffFixed,8,2);       //,ffFixed,8,de
   if form1.CheckBox45.Checked  then //PC output
    resultsOut(form1.CheckBox57.checked,reIns,outputRecord.streamArray[streamIdx[7]]);
   ToStepOutRecord(reIns,StepOutRecord.powerCepstr); //reIns is not modified here (nie jest tu modyfikowany)
   application.ProcessMessages;
  End; {PowerCepstrum}

procedure CCR(var vect:array of double;m:longword;reTmp,imTmp:TdbArr);
  // CCR - Constant Contribution Remove
  //n -    file position (pozycja na pliku)
  //called as: CCR(reIns,i); where: reIns: Power cepstrum analysis results
  var i,k:integer;

  procedure cPCproc(const anal, outRes:boolean;const frameNbr:word; var reMeanVector:array of double; const m, n:word);
  //shows and outputs cPC (time mean power cepstrum vectors - time constant Power Cepstrum contribution)
  //reMeanVector - input data, time mean of cepstrum
  //anal - output only these analyses which are needed for multi analyses
   var j:word;
   Begin
    if not anal then exit;
    temp:=high(reTmp); temp1:=high(reMeanVector);
    for j:=0 to count-1 do reTmp[j]:=reMeanVector[j];   //load time averaged cepstrum (cepstrum uśrednione czasowo)
{cPC} with form2 do
     Begin
      if form1.CheckBox36.checked then Normalize(reTmp);
      if checkBox17.Checked or checkBox97.Checked then          // cPC show, green
       clear:=(not checkbox14.checked) and (n=0);             // check14=PC show
      if checkBox17.Checked then
       SpcDraw(panel4,canvas,reTmp,wspx4,wspy4,centr4,cpstrVizXrange,clear,streamsGraphColors[8],checkBox5.Checked);  //clLime, cepstrum uśrednione czasowo z korektą poczatku (show)
      AlignDrawing(reTmp,reIns,panel4,cpstrVizXrange,wspx4,wspy4,centr4,streamsGraphColors[8],checkBox97,checkBox17);
{!} //if checkBox97.Checked then SpcDraw(panel4,canvas,reIns,wspx4,wspy4,centr4,cpstrVizXrange,true,streamsGraphColors[7],checkBox5.Checked); //clBlue    DEBUG prp; 04112024
     End;{with}
    if outRes then   //--------------cPC output
     resultsOut(form1.CheckBox57.checked,reTmp,outputRecord.streamArray[{streamIdx[8]}m]); //reTmp can be modified here
    ToStepOutRecord(reTmp,stepOutRecord.cPCarr);                                                                     //reTmp is not modified here
    application.ProcessMessages;
   End;{cPCproc}

  procedure vPCproc(const anal,outRes:boolean;const frameNbr:word; var reMeanVector:array of double; const m, n:word);
  //shows and outputs vPC (time variable Power Cepstrum contribution)
  //reMeanVector - input data, time mean of cepstrum
  //vect         - input data, power cepstrum analysis results
  //reIns        - input data,
  //anal - perform only these analyses which are needed for multi analyses
   var j:word;
   Begin
    if not anal then exit;
    for j:=0 to count div 2 do reTmp[j]:=((vect[j]-reMeanVector[j]));  //delete time constant contribution (usuń składową czasową stałą z aktualnego wektora cech)
    try
    for j:=count div 2+1 to count-1 do
     reTmp[j]:=reTmp[count-j];            //---------fill second half
    except
     showMessage('Error occured in the "vPCproc" at j='+intToStr(j))
    end;

{vPC} with form2 do
     Begin
     if form1.CheckBox37.checked then Normalize(reTmp);
     if checkBox16.Checked or checkBox64.Checked then   //--vPC show
      clear:=(not checkbox14.checked) and (not checkbox17.checked) and (n=0);
     if checkBox16.Checked then
      SpcDraw(panel4,canvas,reTmp,wspx4,wspy4,centr4,cpstrVizXrange,clear,streamsGraphColors[9],checkBox5.Checked);  //clYellow, time centralised cepstrum cepstrum scentralizowane czasowo (show)
      AlignDrawing(reTmp,reIns,panel4,cpstrVizXrange,wspx4,wspy4,centr4,streamsGraphColors[9],checkBox64,checkBox16);
 {!}   //  if checkBox64.Checked then SpcDraw(panel4,canvas,reIns,wspx4,wspy4,centr4,cpstrVizXrange,true,streamsGraphColors[7],checkBox5.Checked); //clBlue    DEBUG prp; 04112024
     End;{with}
    if outRes then  //-------------vPC output
     resultsOut(form1.CheckBox57.checked,reTmp,outputRecord.streamArray[{streamIdx[9]}m]);   //reTmp can be modified!
    ToStepOutRecord(reTmp,stepOutRecord.vPCarr); //reTmp nie jest tu modyfikowany
    application.ProcessMessages;
   End;{vPCproc} //(var tempVect:array of double;check30,check37:boolean; var v_v:array of double; out outPut:array of single);

  procedure vPSproc(const anal,outRes:boolean;const frameNbr:word; var reMeanVector:array of double; const m,n:word);
  // computes spektrum freed from time constant  (cPS)  (Yellow)
  //input - vect, reMeanVector, where vect is the power cepstrum and the meanVector is time mean of the power cepstrum
  //output - reTmp, angle
   var j,l:word;
   Begin
    if not anal then exit;                                             //anal - perform only these analyses which are needed for multi analyses
    for j:=0 to count-1 do reTmp[j]:=((vect[j]-reMeanVector[j]));  //delete time constant contribution
    for j:=cpstrPoint to count-cpstrPoint do  reTmp[j]:=0;             //Filtr cepstralny-------------------
    if form2.checkBox30.checked then reTmp[0]:=0;                      //--Check check30 to eliminate multiplicative signal amplification changes
    realFFT(reTmp,ImTmp);                                              //realFFT - ImTmp is set to 0 inside this procedure
    for j:=0 to count-1 do
     try
     angle[j]:=arctan(ImTmp[j]/reTmp[j]);
     except
      angle[j]:=0;
     end;
{vPS}with form2 do
       Begin
        if form1.CheckBox33.checked then Normalize(reTmp);
        if checkBox12.Checked or checkBox21.Checked then   //--------------vPS show
         clear:=(not checkbox9.checked) and (n=0);// and (not checkbox13.checked); 07052017
        if checkBox12.Checked then
         SpcDraw(panel3,canvas,reTmp,wspx3,wspy3,centr3,count_cp,clear,streamsGraphColors[5],checkBox4.Checked); //clYellow,spektrum uwolnione od stałej czasowej
        if checkBox27.Checked then   //--------------vPS phase show
         begin
          clear:=not (checkbox26.checked or checkbox29.checked) and (n=0);
          SpcDraw(panel5,canvas,angle,wspx5,wspy5,centr5,count_cp,clear,streamsGraphColors[5],checkBox4.Checked);    //clYellow, check4 - "clip" for power spectrum
         end;
        l:= high(reIns); if checkBox23.Checked then l:=((l+1) div 2)-1;
        AlignDrawing(reTmp,virt_vect,panel3,l,wspx3,wspy3,centr3,streamsGraphColors[5],checkBox21,checkBox12);
       End; {with form2}
    vPSstDev:=stdDev(reTmp);
    if outRes then  //-------------vPS output
     resultsOut(form1.CheckBox57.checked,reTmp,outputRecord.streamArray[m]);
    ToStepOutRecord(reTmp,stepOutRecord.vPSarr); //reTmp nie jest tu modyfikowany
    application.ProcessMessages;
   End;{vPSproc}

  procedure cPSproc(const anal,outRes:boolean;const frameNbr:word; var reMeanVector:array of double; const m,n:word);
  //m - stream number
  //input -  reMeanVector
   var j,l:word;
   Begin
    if not anal then exit;
    for j:=0 to count-1 do reTmp[j]:=reMeanVector[j];
    for j:=cpstrPoint to count-cpstrPoint do  reTmp[j]:=0;             //Filtr cepstralny-------------------
    if form2.checkBox30.checked then reTmp[0]:=0;//--Check check30 to eliminate multiplicative signal amplification changes
    realFFT(reTmp,ImTmp);  //------------------------spektrum stałej w czasie odpowiedzi impulsowej  centr3+round(panel3.Height/1.75
    for j:=0 to count-1 do
     try
     angle[j]:=arctan(ImTmp[j]/reTmp[j]);
     except
      angle[j]:=0;
     end;
{cPS}with form2 do
      Begin
       if form1.CheckBox32.checked then Normalize(reTmp);
       if checkBox13.Checked or checkBox22.Checked then    //-----------------cPS show
        clear:=(not checkbox9.checked) and (not checkbox12.checked) and (n=0);
        if checkBox13.Checked then
         SpcDraw(panel3,canvas,reTmp,wspx3,wspy3,centr3,count_cp,clear,streamsGraphColors[4],checkBox4.Checked);  //clLime, spektrum uwolnione od składowej zmiennej
       if checkBox28.Checked then    //-----------------cPS phase show
        begin
         clear:=not(checkbox26.checked or checkbox27.checked or checkbox29.checked) and (n=0);
         SpcDraw(panel5,canvas,angle,wspx5,wspy5,centr5,count_cp,clear,streamsGraphColors[4],checkBox4.Checked);  //clLime
        end;
       l:= high(reIns); if checkBox23.Checked then l:=((l+1) div 2)-1;
       AlignDrawing(reTmp,virt_vect,panel3,l,wspx3,wspy3,centr3,streamsGraphColors[4],checkBox22,checkBox13);
      End;{with}
    if outRes then //--------------cPS output
     resultsOut(form1.CheckBox57.checked,reTmp,outputRecord.streamArray[m]);
    ToStepOutRecord(reTmp,stepOutRecord.cPSarr[n]);  //reTmp nie jest tu modyfikowany
    application.ProcessMessages;
   End;{cPSproc}

 procedure HistError(const s:shortString; const frameNbr:integer;const history:Thistory);
  var j:integer;
   var s1:shortString;
  Begin
   j:=high(History)+1;
    if j<>frameNbr then
    begin
     if frameNbr>j then s1:='The "history" array is too small' else s1:='The "history" array is too big';
     showMessage('The averaging range value, i.e. the "'+form1.TabSheet8.Caption +'\'+form1.label92.Caption+
     '" value, now equal "'+intToStr(frameNbr)+'", should not differ from "'+intTostr(j)+
     '"!'#13#10'Program error, called from "'+s+'".'+s1+'. The averaging process will not be executed properly!');
    end;
  End;{HistError}

   procedure meanActualize(const i,frameNbr:word; const k:longWord; var reMeanVector:array of double; var reHistory:THistory);
   //input - vect, reHistory; vect received from CCR header, is the PC analysis result
   //output - reMeanVector
   //k - spectrum slice nbr (numer widma chwilowego)
   //i:=k mod frameNbr; write-down position on the ring buffer (buffPosP; pozycja zapisu nowej wartości na buforze pierścieniowym)
    var j:word;
    Begin
     HistError('constantContributionRemove 2.',frameNbr,reHistory);
     temp:=high(reMeanVector); temp1:=high(vect); temp2:=high(reHistory[0]); //debug
     for j:=0 to count div 2 do
      reMeanVector[j]:=reMeanVector[j]-reHistory[i][j];  //odejmij od średniej jej pierwszy (najstarszy) składnik
     for j:=0 to count div 2 do
      reHistory[i][j]:=vect[j]/frameNbr;                 //wprowadź składnik średniej wektora cechy do bufora (historii) {było reHistory[i] 31.12.12}
     for j:=0 to count div 2 do
      reMeanVector[j]:=reMeanVector[j]+reHistory[i][j]; //dodaj do średniej najnowszy składnik
     for j:=count div 2+1 to count-1 do reMeanVector[j]:=reMeanVector[count-j];  //fill second half
    End;{meanActualize}

 procedure historyActualize(const slcNbr:longword; const frameNbr0, frameNbr:word; var reHistory:Thistory; var reMeanVector:array of double);
 //slcNbr - spectrum slice nbr (numer widma chwilowego)
 var i,j:integer;
  old_buffPos,new_buffPos,beg0,beg1:word;
  tmp_reHistory:THistory;

 procedure loadTmpBuff;
 var i:integer;
 Begin
  for i:=0 to frameNbr0-1 do
    tmp_reHistory[i]:=reHistory[i]; //mean members vector at a time j
 End;{loadTmpBuff}

 procedure reloadHist;   //ładuje końcówkę tmp_hist z odpowiednim obrotem

  function idx(frameNbr,i:integer):integer;
   Begin
    if i>=0 then result:=i
    else result:=frameNbr+i;
   End;{idx}

  var i,j,k : integer;
  Begin
  for i:=0 to frameNbr-1 do                   //fill the history's buffer with zero-vectors when the averaging period is longer (wypełnić wektorami zerowymi pustą część bufora, jeśli okres uśredniania się wydłużyl)
   for j:=0 to count div 2 do reHistory[i,j]:=0;
   if frameNbr<frameNbr0 then k:=frameNbr
   else k:=frameNbr0;
   j:=beg1;
    for i:=beg0 downto beg0-k+1 do
     begin
      reHistory[idx(frameNbr,j)]:=tmp_reHistory[idx(frameNbr0,i)];
      dec(j);            //dec, because back-wise read and load
     end;
  End;{reloadHist}

  procedure computeMean;
   var i,j,k,l:integer;
   Begin
    k:=frameNbr-1; l:=count div 2;
    for j:=0 to l do reMeanVector[j]:=0;
    for j:=0 to l do
     begin
      i:=0;
      while i<= k do  //"while", because "for" runs to k+1!!
       begin
        reMeanVector[j]:=reMeanVector[j]+reHistory[i,j];
        inc(i)
       end;{while}
      end;{for j}
   End;{computeMean}

  Begin  //=======================================historyActualize=========================
   old_buffPos:=(slcNbr) mod frameNbr0;    beg0:=old_buffPos;
   new_buffPos:=(slcNbr) mod frameNbr;     beg1:=new_buffPos;
   HistError('historyActualize, 1.',frameNbr0,reHistory);
   for i:=0 to frameNbr0-1 do       //rescale history
    for j:=0 to count div 2 do reHistory[i,j]:=reHistory[i,j]*frameNbr0/frameNbr;
   //shift buffer content to the begining when averaging period was diminished (przesunąć wycinek na początek bufora (gdy pomniejszamy jest okres uśredniania))
   if frameNbr<frameNbr0 then SetLength(tmp_reHistory,frameNbr0,count div 2)
   else SetLength(tmp_reHistory,frameNbr,count div 2+1);
    loadTmpBuff;
    SetLength(reHistory,frameNbr,count div 2+1);
    reLoadHist;
    SetLength(tmp_reHistory,0);  //0 - remove temporary dynamic variables (usuń tymczasowe  zmienne dynamiczne)
    computeMean;                //oblicz nową średnią
  End; {historyActualize}

  procedure bundleCCRperformer(var frameNbr,frameNbr0:integer;var reHistory:Thistory; var reMeanVector:array of double; const k:dword; const m,n:word);
   //k - spectrum slice nbr (numer widma chwilowego, slcNbr)
   //m - stream number (to which results are directed) - numer strumienia wynikow
   //n - mean number = number of average constant
   //frameNbr,frameNbr0 - averaging constant: current and previous
    Begin
     HistError('constantContributionRemove 1.',frameNbr0,reHistory);
     i:=k mod frameNbr;                                                   //position on the ring buffer (pozycja na buforze pierścieniowym, buffPosP)
     ringBuffChangePointArr[n]:=i;                                        //potrzebne do opisu slajdu w raporcie (punkt zapisu na buforze)
     if frameNbr<>frameNbr0 then                                          //history actualization when averaging period was changed (aktualizacja historii przy zmianie okresu uśredniania)
      begin
       historyActualize(k,frameNbr0,frameNbr,reHistory,reMeanVector);
       frameNbr0:=frameNbr                                                //uaktualnić zwrotnie bufor frameNbr0Arr
      end;
     meanActualize(i,frameNbr,k,reMeanVector,reHistory);                  //n=0 - output results of cPc, vPC and vPS only for  mean with 0-th number on the list of period of averaging i.e. when working in basic mode (i.e. not in multiaveraging mode);
     case form1.RadioGroup4.ItemIndex of
      0:vPSproc((form2.CheckBox49.Checked or saveSlide),form1.CheckBox49.Checked,frameNbr,reMeanVector,m,n); //shows and outputs vPS (i.e. Power Spectrum time Variable contribution)
      1:cPSproc((form2.CheckBox50.Checked or saveSlide),form1.CheckBox49.Checked,frameNbr,reMeanVector,m,n); //shows and outputs cPS (i.e. Power Spectrum time Constant contribution) cPS is output for each mean, i.e. both in basic and in multiaveraging mode (jest wyprowadzane dla kazdej sredniej, tj w obydwu trybach pracy: podstawowym i "multimean")
      2:vPCproc((form2.CheckBox57.Checked or saveSlide),form1.CheckBox49.Checked,frameNbr,reMeanVector,m,n); //shows and outputs vPC (i.e. Power Cepstrum time Variable contribution)
      3:cPCproc((form2.CheckBox58.Checked or saveSlide),form1.CheckBox49.Checked,frameNbr,reMeanVector,m,n); //shows and outputs cPC (i.e. Power Cepstrum time Constant contribution)
     end;
     application.ProcessMessages;
    End; {bundleCCRperformer}

 procedure singleCCRperformer(var frameNbr,frameNbr0:integer;var reHistory:Thistory; var reMeanVector:array of double; const k:dword; const n:word);
   //k - spectrum slice nbr (numer widma chwilowego, slcNbr)
   //m - stream number (to which results are directed) - numer strumienia wynikow
   //n - mean number = number of average constant
   //frameNbr,frameNbr0 - averaging constant: current and previous
    Begin
     HistError('constantContributionRemove 1.',frameNbr0,reHistory);
     i:=k mod frameNbr;                                                   //position on the ring buffer (pozycja na buforze pierścieniowym, buffPosP)
     ringBuffChangePointArr[n]:=i;                                        //potrzebne do opisu slajdu w raporcie (punkt zapisu na buforze)
     if frameNbr<>frameNbr0 then                                          //history actualization when averaging period was changed (aktualizacja historii przy zmianie okresu uśredniania)
      begin
       historyActualize(k,frameNbr0,frameNbr,reHistory,reMeanVector);
       frameNbr0:=frameNbr                                                //uaktualnić zwrotnie bufor frameNbr0Arr
      end;
     meanActualize(i,frameNbr,k,reMeanVector,reHistory);                  //n=0 - output results of cPc, vPC and vPS only for  mean with 0-th number on the list of period of averaging i.e. when working in basic mode (i.e. not in multiaveraging mode);
     cPCproc((form2.CheckBox58.Checked or saveSlide),form1.CheckBox46.Checked,frameNbr,reMeanVector,streamIdx[8],n);     //shows and outputs cPC (i.e. Power Cepstrum  time Constant contribution)
     vPCproc((form2.CheckBox57.Checked or saveSlide),form1.CheckBox47.Checked,frameNbr,reMeanVector,streamIdx[9],n);    //shows and outputs vPC (i.e. Power Cepstrum  time Variable contribution)
     vPSproc((form2.CheckBox49.Checked or saveSlide),form1.CheckBox43.Checked,frameNbr,reMeanVector,streamIdx[5],n);   //shows and outputs vPS (i.e. Power Spectrum  time Variable contribution)
     cPSproc((form2.CheckBox50.Checked or saveSlide),form1.CheckBox42.Checked,frameNbr,reMeanVector,streamIdx[4],n);  //shows and outputs cPS (i.e. Power Spectrum  time Constant contribution) cPS is output for each mean, i.e. both in basic and in multiaveraging mode (jest wyprowadzane dla kazdej sredniej, tj w obydwu trybach pracy: podstawowym i "multimean")
     application.ProcessMessages;
    End; {singleCCRperformer}

   var n:byte;
   {
   called as: CCR(reIns,i); where: reIns: Power cepstrum analysis results
   frameNbrArr,frameNbr0Arr -  lists of averaging time periods: current and previous (listy okresów uśredniania: bieżąca i poprzednia)
   }
   Begin      //-----------------------CCR-------------------------------------
    k:=(m div jumpNbrSamples);                                       //k - spectrum slice nbr (slcNbr, numer widma chwilowego); n - file position (pozycja na pliku)
    n:=0;
    singleCCRperformer(frameNbrArr[n],frameNbr0Arr[n],reHistoryArr[n],reMeanVectorArr[n],k,n); //first occurence of cPS
    n:=0;
    if form1.checkbox49.Checked and  form1.checkBox15.Checked then   //49: f1/outputs, 11. multimean cPS; 15: f1/Analysis, Power Cepstrum (PC)
     while (n<NbrOfMultiMean) do
      begin
       inc(n);
       bundleCCRperformer(frameNbrArr[n],frameNbr0Arr[n],reHistoryArr[n],reMeanVectorArr[n],k,streamIdx[10+n],n);
      end;
   End;{CCR}

  procedure SmoothPS;   //sPS
   var j,l:Integer;
   Begin //---------------------------------- cepstrally smoothed Power Spectrum--------------------------
    for j:=cpstrPoint to count-cpstrPoint do  reIns[j]:=0;                                          //Filtr cepstralny-------------------
    if form2.checkBox30.checked then reIns[0]:=0;
    realFFT(reIns,ImIns); //                              /255   13.12.12 rfft_calc(index_mix,maxpower,sinar,cosar,reIns,ImIns,count); //był                                                       //- odwracanie cepstrum 131212
    with form2 do
     Begin
      if form1.CheckBox31.checked then Normalize(reIns);
      if checkBox10.Checked or checkBox19.Checked then             //sPS
       clear:=(not checkbox9.checked) and (not checkbox13.checked) and (not checkbox12.checked);
      if checkBox10.Checked then
       SpcDraw(panel3,canvas,reIns,wspx3,wspy3,centr3,count_cp,clear,streamsGraphColors[3],checkBox4.Checked);  //clBlack, - odwrócone cepstrum - spektrum wygładzone
      l:= high(reIns); if checkBox23.Checked then l:=((l+1) div 2)-1;
      AlignDrawing(reIns,virt_vect,panel3,l,wspx3,wspy3,centr3,streamsGraphColors[3],checkBox19,checkBox10);
     End;{with}
    if form1.CheckBox41.Checked then //sPS output   check57=Save choosed streams
      resultsOut(form1.CheckBox57.checked,reIns,outputRecord.streamArray[streamIdx[3]]);
    ToStepOutRecord(reIns,StepOutRecord.smoothedSpectr); //reIns  is not modified here
    application.ProcessMessages;
   End; {SmoothPS}

   procedure SmoothMelPS; //msPS
    var l:word;
   Begin   //----------------------------------CEPSTRALY SMOOTHED POWER SPECTRUM Xaxis units - mel -------------------
     melTrans(reIns);                                                                                           //transformacja do meli
     with form2 do
      Begin
       if form1.CheckBox34.checked then Normalize(reIns);
       if checkBox11.Checked or checkBox20.Checked then  //msPS
        clear:=(not checkbox9.checked) and (not checkbox13.checked) and (not checkbox12.checked) and not(checkbox10.checked);
       if checkBox11.Checked then
        SpcDraw(panel3,canvas,reIns,wspx3,wspy3,centr3,count_cp,clear,streamsGraphColors[6],checkBox4.Checked);  //clRed, spektrum wygładzone po transformacji do meli
       l:= high(reIns); if checkBox23.Checked then l:=((l+1) div 2)-1;
       AlignDrawing(reIns,virt_vect,form2.panel3,l,wspx3,wspy3,centr3,streamsGraphColors[6],form2.checkBox20,checkBox11);
      End;{with}
    if form1.CheckBox44.Checked then   //mel, msPS output
     resultsOut(form1.CheckBox57.checked,reIns,outputRecord.streamArray[streamIdx[6]]);
    ToStepOutRecord(reIns,StepOutRecord.melSmoothSpectr); // reIns nie jest tu modyfikowany
    application.ProcessMessages;
   End;{SmoothMelPS}

   procedure melCepstrum;   //mPC
   var i:word;
   Begin  //------------------------------------------------------MEL-POWER CEPSTRUM ------------------------
    for i:=0 to count-1 do  ImIns[i]:=0;
    rfft_calc(index_mix,maxpower,sinar,cosar,reIns,ImIns,count);
    with form2 do
     Begin
      if form1.CheckBox38.checked then Normalize(reIns);
      if checkBox15.Checked or checkBox63.Checked then
       clear:=(not checkbox14.checked) and (not checkbox16.checked) and (not checkbox17.checked);
      if checkBox15.Checked then
       SpcDraw(panel4,canvas,reIns,wspx4,wspy4,centr4,cpstrVizXrange,clear,streamsGraphColors[10],checkBox5.Checked);  //clRed
      AlignDrawing(reIns,reTmp,panel4,cpstrVizXrange,wspx4,wspy4,centr4,streamsGraphColors[10],checkBox63,checkBox15);
{!} //    if checkBox63.Checked then SpcDraw(panel4,canvas,reTmp,wspx4,wspy4,centr4,cpstrVizXrange,true,streamsGraphColors[7],checkBox5.Checked); //clBlue    DEBUG prp; 04112024
     End;{with}
    if form1.CheckBox48.Checked then //mel PC
     resultsOut(form1.CheckBox57.checked,reIns,outputRecord.streamArray[streamIdx[10]]);
    ToStepOutRecord(reIns,StepOutRecord.melCepstr); // reIns nie jest tu modyfikowany
    application.ProcessMessages;
   End;{melCepstrum}

function stepWiseManager(var ism:longInt; const Jump:word; out sWM_savedRec:dword):boolean;
 var i:integer;//needed for tryStrToInt

    begin
     result:=False;
     if  onScroll or form2.CheckBox2.Checked then  //------------------------------------------------------wykonanie krokowe
      Begin
       rep:=false;
       repeat
        application.ProcessMessages;         //konieczne, aby program reagował w tej pętli na kliknięcia przycisków!!!
        case  manager of
         #0  : inc(ism,jump);                //powiększyć "ism" gdy jest wyłączany step-checkbox 18052013
         #2  : manager:=#0;                  //23022024
         'C' : begin result:=True; Exit end; //break

         'B' : if (ism>=jump) or windowsSearching then    //back
                begin
                 timeBack:=true; t0TimeBack:=true;   spongeShift:=2*form2.panel9.Width;
                 if ism>=jump then dec(ism,jump);                                               //go back to previous portion cofnąć się do poprzedniej porcji
                 if ism<=0 then form2.button2.Enabled:=false;
                 manager:=#0;
                end
               else form2.Button2.Enabled:=false;                             //"Back"

         'E' : begin      //change in output streams, begin analysis from scratch
                if messageDlg('Would you like to start analyses from scratch?',mtWarning, [mbYes, mbNo],1)=mrYes  //23012025
                then
                 begin
                 ism:=0;   sWM_savedRec:=0;   prevSliceNbr:=0;
                 Rewrite(outPutRecordFile);
                 whatToSave(true);
                 ShowMessage('Analyses will start from scratch!');
                 end;
                FramesRepaint(count_cp,T0Clear);
                manager:=#0; //'T';23102023
               end;


         'e': begin
               FramesRepaint(count_cp,true);
               manager:='t';
              end;

         'F' : manager:=#0;                      //leave the manager when frame number was changed

         'G' : begin                             //go to
                form2.checkBox2.Checked:=true;   // stepwise
                if tryStrToInt(inputBox('Jump to a sample with a number','the sample number',intToStr(ism)), i)
                then
                 if (i<>ism) and (i>=0) then
                 begin
                  if i>nbrOfData-count-1 then begin i:=nbrOfData-count-1; showMessage('Command can not exceede number_of_data-windows_width, i.e. '+intToStr(nbrOfData-count-1)+'. Jump to this number will be performed') end;
                  ism:=i;
                  savedRec:=i div jump;
                  showMessage('You should repeat a signal analyses from scratch because of introduced here discontinuity');
                 end;
                manager:=#0;
               end;

         'H' : if reportSave then begin saveHistory(OutPutRecord.out_sliceNbr);  manager:=#0 end;//write down the averaging history to the "slide" file (for debuging purposes)

         'N' : begin inc(ism,jump);form2.Button2.Enabled:=true; manager:=#0 end;   //next, początek następnej porcji; button2 - "Back"

         'R' : begin //repaint, evoked automatically, when you click the "reapaints frames" button or "form2.check4|5|6", i.e. ("clip", "clip", "big scale")
                form2.CheckBox1.Checked:=true;  //show graphs
                form2.CheckBox2.Checked:=true;  //continuos|step             //stepwise
                PCrange:=PCrangeControl;        //23112024
                FramesRepaint(count_cp,T0Clear); onScroll:=false;
                label53Caption;
                with form2 do if Button4.CanFocus then Button4.setFocus;
                manager:=#0;
               end;

         'r' : begin                           //"repeat" command
                rep:=true;                     // do not clear graph when repeat command was sent
                form2.checkBox2.Checked:=true; // stepwise
                manager:=#0;
               end;

         'S' : begin //write down a slide;
                saveSlide:=true;
                manager:='r'
               end;

         'T' : begin //go back to actualize averaging buffers
                if ism>maxFrameNbr*jump then dec(ism,maxFrameNbr*jump)
                else ism:=0;
                timeBack:=true;   t0TimeBack:=true; //should precede the next instruction checkbox2.checked:=true in order to prevent locking the Diagnostic Box in
                form2.CheckBox1.Checked:=true;    //show graphs
                form2.CheckBox2.Checked:=false;  //step/continues  it is a must to restore analysis state after changes in parameters of analyses when averaging is needed
                PCrange:=PCrangeControl;        //25112024
                framesRepaint(count_cp,T0Clear);       // blocked 28032024  activated 05042024
                manager:=#0; T0Clear:=True;      //11042024
               end;

         't' : begin //go back to actualize averaging buffers, lock outputs
                if ism>maxFrameNbr*jump then dec(ism,maxFrameNbr*jump)
                else ism:=0;
                timeBack:=true;                      //should precede the next instruction checkbox2.checked:=
                if not form2.checkbox24.checked then //"Lock diagnostic box"
                form2.CheckBox1.Checked:=True;       //added 25102023
                if not windowsSearching then         //do not turn off step mode automatically when not windows searching is pending
                 form2.CheckBox2.Checked:=false;     //step mode
                manager:=#0;
               end;

         'V' : begin // 1-sided|2-sided graphs
                if form1.CheckBox6.checked then count_cp:=cp else count_cp:=count;
                manager:='R';
               end;

         'Y' : begin   //scratch
                manager:='E';
                T0sliceNbrGlob:=high(T0sliceNbrGlob); TimeBack:=false; form2.button2.Enabled:=false;
                FramesRepaint(count_cp,true); onScroll:=false;
                if form2.Button4.CanFocus then form2.Button4.setFocus; //Next
               end;
         'Z' : ;
         end;
       until manager=#0;
       manager:=#1;
      End{if}
     else inc(ism,jump);
     application.ProcessMessages;
    end;{stepWiseManager}

 function AnalysisPerformer(var annotation:boolean; const iw:dword; var inpSliceNbr:dword; const savedRec:dword;callChain:string):boolean;
  var  j : word;

  procedure signalToOutStream(xr:array of double);
 //writes down a smallInt signal portion to one single type stream - every two integer values into one single type value
   var singInt:TsingInt;   i,j:word;
   Begin
    i:=0;
    for j:=0 to count div 2 -1 do
     begin
      singInt[0]:=round(xr[i]);
      singInt[1]:=round(xr[i+1]);
      inc(i,2); //load two integer values to one value of the type single
      outputRecord.streamArray[streamIdx[0],j]:=single(singInt);
     end;{for}
    singInt[0]:=32000; singInt[1]:=-32000;          //empty values finishes wav piece
    outputRecord.streamArray[streamIdx[0],count div 2]:=single(singInt);
   End; {signalToOutStream}

 procedure personDescr(const i,k:longWord);  //person description
  //i - wave sample number
  //k - slice number
  Begin
   outPutrecord.person:=cath.TcPerson;//char(personNr+64);  second classifier (drugi klasyfikator zdarzeń - wg osób wymiana na cath.person 13032014)
   if not (outPutrecord.person in personSet) then with form2 do
   begin
    include(personSet,outPutrecord.person); inc(personNbr);
    Label58.Caption:=intToStr(personNbr);  Label67.Caption:=cath.TcPerson; Label10.Caption:=cath.TcGender; Label13.Caption:=intToStr(cath.TcAge);
    Label60.Caption:=intToStr(k);
    with memo2 do Text:=Text+intToStr(i)+#9+intToStr(k)+#9+intToStr(personNbr)+#9+outPutrecord.person+#13#10;
 // memo2.Lines.Move(0,count);//24.05.08
   end;
  End;{personDescr}

 function cathegoryDescription(const id:longWord):boolean;
  Begin
   cathegoryDescription:=true;
      if windowsSearching then  seek(cathFile,id) //28042025 (should be checked its functioning in the mode Windows Search)
   else
   case form2.RadioGroup9.ItemIndex of   //28042025
    0:seek(cathFile,id);            //every wav sample is assigned some phon sign, however we have to read a sign assigned to the 1-th sample of an actually taken portion of the wave signal to analysis
    1: seek(cathFile,id+cp);           //every wav sample is assigned some phon sign, however we have to read a sign assigned to the 1-th sample or to the sample fro the windows center of an actually taken portion of the wave signal to analysis
   end;

   if not eof(cathFile) then read(cathFile,cath);
   OutPutRecord.phon:=cath.TcPhon;
   if not (cath.TcPhon in phonSet) then                 //cathegories values counters
    with form2 do
     begin
      include(phonSet,cath.TcPhon); inc(phonNbr);
      Label56.Caption:=intToStr(phonNbr);
      Label59.Caption:=intToStr(OutPutRecord.out_sliceNbr);
      with memo1 do Text:=Text+intToStr(id)+#9+intToStr(OutPutRecord.out_sliceNbr)+#9+intToStr(phonNbr)+#9+cath.TcPhon+#9+intToStr(byte(cath.TcPhon))+#13#10;
     end;
    OutPutRecord.gender:=cath.TcGender;                 //---------------------gender--------------
    if not (OutPutRecord.gender in genderSet) then
     with form2 do
      begin
       include(genderSet,OutPutRecord.gender);
       inc(genderNbr);
       Label47.Caption:=intToStr(genderNbr);
       Label49.Caption:=intToStr(OutPutRecord.out_sliceNbr);
       with memo4 do Text:=Text+intToStr(id)+#9+intToStr(OutPutRecord.out_sliceNbr)+#9+intToStr(genderNbr)+#9+cath.TcGender+#9+intToStr(byte(cath.TcGender))+#13#10;
      end;
    OutPutRecord.age:=char(cath.TcAge);                 //---------------------age--------------
    if not (OutPutRecord.age in ageSet) then
     with form2 do
      begin
       include(ageSet,OutPutRecord.age);
       inc(ageNbr);
       Label46.Caption:=intToStr(ageNbr);
       Label48.Caption:=intToStr(OutPutRecord.out_sliceNbr);
       with memo3 do Text:=Text+intToStr(id)+#9+intToStr(OutPutRecord.out_sliceNbr)+#9+intToStr(ageNbr)+#9+intToStr(cath.TcAge)+#9+intToStr(cath.TcAge)+#13#10;
      end;
   form2.label65.caption:=cath.TcPhon;
   personDescr(id,OutPutRecord.out_sliceNbr);
   form2.label67.caption:=intToStr(personNbr);
  End;{cathegoryDescription}

 procedure timeBackHandler;
  Begin
   if inpSliceNbr=savedRec then                 //stop return in stepWiseManager making timeBack:=false
    if timeBack then
     begin
      timeBack:=false;
     // form2.CheckBox1.Checked:=true;           //show graphs
      form2.GroupBox1.Enabled:=not form2.CheckBox24.Checked; //enable Diagnostic Box, check24="Lock diagnostic box"
      if not windowsSearching  then //do not go to step mode when windows search is pending
       begin
        if not form2.CheckBox2.Checked then with form2 do  //step mode
         begin
          //showMessage('The analysis was stopped due to the "'+button2.Caption+'" commands, turn on the "'+checkbox2.Caption+'" to continue');   //   debug prp.
          CheckBox2.Checked:=true;                         //Step Wise mode
          if Button4.CanFocus then Button4.SetFocus;       //Next
          manager:='R';                                    //actualize the X axis description and T0sliceNbrGlob
         end;
        form2.CheckBox1.Checked:=true;                     //show graphs
       end;{not windowsSearching}
      manager:=#1                                          //in order to stop return in stepWiseManager
     end{timeBack}
    else //if timeBack
   else  //if inpSliceNbr=savedRec
    if (timeBack and not form2.checkBox62.checked) then form2.CheckBox1.Checked:=false; //check62=Averaging show; check1=show graphs    block 29122023
  End;{timeBackHandler}

 Begin //----------------------------------analysisPerformer----------------------------------------
  callChain:=callChain+'>analysisPerformer';
  OutPutRecord.out_sliceNbr:=iw div jumpNbrSamples+1;
  result:=true;
  timeBackHandler;
   if f2Radio7Changed then                                //windows shape changer,  compute and show new weighting window
    begin
     f2Radio7Changed:=false;
     winNbr:=form2.RadioGroup7.ItemIndex;  gaussStdev:=strToInt(form2.Edit4.Text)/gaussScaler;
     rectFill:=strToInt(form2.Edit7.Text) mod (count div 2); form2.Edit7.Text:=intToStr(rectFill);
     WindowsWeights(winNbr,gaussStDev,windowWeights,WeightMean,count);
    end;
   for j:=0 to count-1 do xr[j]:=speech[iw+j];             //----------Porcja do analiz--//iw - licznik próbek sygnału powiększany skokowo o rozmiar porcji,//j - licznik próbek składających się na porcje
   if form1.CheckBox5.Checked and spcSave then signalToOutStream(xr);     //Output/"Input window"  loads
   if (inpSliceNbr>savedRec) or windowsSearching then result:=cathegoryDescription(iw); //or windowsSearching to evaluate cathegory labels on the interface screen
   form2.label63.caption:=intToStr(OutPutRecord.out_sliceNbr); //show sliceNbr
   form2.label61.caption:=intToStr(iw);
   with form1 do
    begin                                        //"Analysis" tab sheet:
     InputPrepare(annotation,iw);                //Prepares slides and performs diagnostic or testing transformations and shows input oscillogramms
     if checkBox14.Checked or saveSlide then PowerSpectrum;   //PS;
     if checkBox15.Checked or saveSlide then                  //PC, power Cepstrum
      begin
       PowerCepstrum(iw);                        //PC; results: reIns,imIns
       CCR(reIns,iw,reTmp,imTmp);                //CCR - constantContributionRemove; reIns: Power cepstrum analysis results
      end;
     if form2.checkBox1.Checked or form2.checkBox94.Checked then T0plot(iw,T0,callChain);    //result=T0 in this call (w tym wolaniu)
     for j:=0 to high(retmp) do reTmp[j]:=reIns[j];           //in order to support the mPC aligning; 05.11.2410
     if checkBox16.Checked or saveSlide then SmoothPS;        //sPS
     if checkBox11.Checked or saveSlide then SmoothMelPS;     //msPS
     if checkBox12.Checked or saveSlide then MelCepstrum;     //mPC
    end;
 End;{analysisPerformer}

procedure TakePortions(out k:longWord; const nbrOfdata:dWord;reTmp,imTmp:TdbArr;out savedRec,prevSliceNbr,waveFileWinNbr:dword; out i0,i:longint; var annotation:boolean;callChain:string);
{
pobiera dane przez ruchome okno i kieruje je do analiz
speech    -sygnał mowy, wczytany w całości do pamięci RAM
nbrOfdata -nuber of data read from an input file
k         -licznik przeanalizowanych porcji
savedRec    -counter of saved results records
i - nr w sygnale pierwszej próbki w porcji
}
var
 j : longWord;

  procedure minMaxShow(checked:boolean;label21,label22,label11,label12:TLabel;min2,max2,min1,max1:Extended);
   begin
    if Checked then
     begin
      label21.Caption:=floatToStrF(min2,fffixed,7,3);
      label22.Caption:=floatToStrF(max2,fffixed,7,3);
     end
    else
     begin
      label21.Caption:='-';
      label22.Caption:='-';
     end;
    label11.Caption:=floatToStrF(min1,fffixed,7,3);
    label12.Caption:=floatToStrF(max1,fffixed,7,3);
    Application.ProcessMessages
   end; {minMaxShow}

 label finish;
  //TakePortions(out k:longWord; const nbrOfdata:dWord;reTmp,imTmp:TdbArr;out savedRec,prevSliceNbr,waveFileWinNbr:dword; out i0,i:longint; var annotation:boolean;);
  begin    //---==============================TakePortions======================-----------------------
   callChain:=callChain+'>TakePortions';
   rep:=false;  I:=0;    j:= fileSize(cathFile); //debug prp 03122023
   While (i<=waveFileWinNbr) and (i<=fileSize(cathFile)) do              //<=, because the "i" increase is made at the end of "while" before a portion analysing, which will be performed in next turn
    begin   iGlob:=i;                                                             //last portion can not protrude the signal samples sequence
     if not AnalysisPerformer(annotation,i,OutPutRecord.out_sliceNbr,savedRec,callChain) then break;         //File '+cathFilePath+' is too short,
     application.ProcessMessages;
     if OutPutRecord.out_sliceNbr>savedRec then                              //save only not saved record (ignore records from the "back" commands
      begin
       outrecordToFile(100+i);                                            //zapis bieżących wyników analizy
       if OutPutRecord.out_sliceNbr<>prevSliceNbr+1 then
        showMessage('There is something wrong with program. The analysed portion (nbr '+intToStr(OutPutRecord.out_sliceNbr)+
                    ') does not follow immediately the previous one (nbr '+intToStr(prevSliceNbr)+').');
       inc(savedRec);                                                    //savedRec - "record Saved" counter of saved results records
       prevSliceNbr:=OutPutRecord.out_sliceNbr;
      end;{if}
     form2.label29.Caption:='';
     if form2.checkbox2.Checked then form2.label29.Caption:=form2.label29.Caption+'Uncheck "'+form2.CheckBox2.Caption+'"'#13#10'to turn off stepwise analysis'
     else form2.label29.Caption:=form2.label29.Caption+'Check "'+form2.CheckBox2.Caption+'"'#13#10'to turn on stepwise analysis';
     saveSample; //zapisz slide do raportu
     if StepWiseManager(i,jumpNbrSamples,savedRec) then
      begin
       dec(prevSliceNbr);
       goto finish;
      end;     //"Break"
    end;{While}
 finish:
   i0:=i;
  end;{TakePortions}

 procedure slidesRecordInit;
  Begin
    with stepOutRecord do   //initialization of the slides record
    begin
     setLength(signal,count);
     setLength(weighedSignal,count);
     setLength(powerSpectr,count);
     setLength(VPSarr,count);                            //variable power spectrum component
     setLength(CPSarr,NbrOfMultiMean+1,count);          //constant power spectrum component
     setLength(slide_angle,count);                     // wrapped complex spectrum angle
     angleTemp:=high(angle);                          //debug
     setLength(smoothedSpectr,count);                // cepstrally smoothed spectrum spektrum j.w. wygładzone cepstralnie
     setLength(melSmoothSpectr,count);              // smoothed mel power spectrum spektr j.w. po transformacji melowej
     setLength(powerCepstr,count);                 // Power Cepstrum cepstrum mocy
     setLength(vPCarr,count);                     //variable power cepstrum component
     setLength(cPCarr,count);                    //constant power cepstrum component
     setLength(melCepstr,count);
     slide_sliceNbr:=high(signal);
     slide_sliceNbr:=low(signal);
    end;
  End; {slidesRecordInit}

  procedure NormCheckBoxesStatesToReport;
  Begin
  writeln(reportFile,'Normalised streams:');
  with form2 do
   begin
    if checkBox82.checked then writeln(reportFile, checkBox7.Caption);
    if checkBox83.checked then writeln(reportFile, checkBox8.Caption);
    if checkBox84.checked then writeln(reportFile, checkBox9.Caption);
    if checkBox85.checked then writeln(reportFile,checkBox10.Caption);
    if checkBox86.checked then writeln(reportFile,checkBox11.Caption);
    if checkBox87.checked then writeln(reportFile,checkBox12.Caption);
    if checkBox88.checked then writeln(reportFile,checkBox13.Caption);
    if checkBox89.checked then writeln(reportFile,checkBox14.Caption);
    if checkBox90.checked then writeln(reportFile,checkBox15.Caption);
    if checkBox91.checked then writeln(reportFile,checkBox16.Caption);
    if checkBox92.checked then writeln(reportFile,checkBox17.Caption);
   // if checkBox93.checked then writeln(reportFile,checkBox93.Caption);
   end;{with}
 End;{NormCheckBoxesStatesToReport}

 procedure spectrAnalyser(out nbrOfData:dword; var savedRec,prevSliceNbr:dword;callChain:string);
  var
                        WaveCaption : TWaveCaption;
                   SmallIntWaveFile : TSmallIntFile;
                   waveFileWinNbr,k : longWord;        //k- slices counter, nbrOfdata - nuber of data read from input file
                               i0,i : longint;
                          tmp1,tmp2 : string;
                                  l : int64;
                         annotation : boolean;
                                  s : string;

 procedure FileOpening(var FileDir:pathStr;Title:pathStr;ext:ExtStr; var label0,label1,label2:TLabel);
 var date,size:pathStr;
 Begin
  repeat
   while not OpenFile(FileDir,Title,ext) do  //wskazuje ścieżkę do pliku danych - waveFilePath
    begin
     case MessageDlg('[FileOpening] You haven''t pointed a file or "'+FileDir+'" does not exist. You can retry or'+
     ' program will be halted.'#13#10'Check, repair or delete the init file, i.e. the "'+initDir+
     '" if the file path is incorrect or click "YES" to call "Open" window with empty initial directory',mtWarning,[mbYes,mbAbort,mbRetry],1)
     of
     mrAbort : Halt;           //3
       mrYes : begin          //6;
                FileDir:=''; //call "Open" window with empty initial directory
                OpenFile(FileDir,Title,ext);
                break
               end;
     end;{case}
    end;{while}
   if fileExists(FileDir) then break
   else    //when cancel was chosen
    if MessageDlg('[FileOpening] You have pointed false file "'+FileDir+'". You can retry or program will be halted',mtWarning,
                   [mbAbort,mbRetry],1)=mrAbort then  Halt
  until false;
  try
   fileDateSize(FileDir,date,size);
   label0.Caption:=FileDir;
   label1.caption:=date;
   label2.caption:=size;
   application.ProcessMessages;
 except
  showMessage('There was sth wrong with the "'+FileDir+'". Its size could be not evaluated.');
 end;
 End;{FileOpening}

   procedure extractFileDirAndFileName(var fileDir,FileName,path:pathStr);
   begin //create fileDir and fileName from "path"
    fileDir:=extractFileDir(path);
    FileName:=extractFileName(path);
    delete(FileName,length(FileName)-length(extractFileExt(FileName))+1,length(extractFileExt(FileName)));   //delete extension from file name
   end;{extractFileDirAndFileName}

 procedure wavAndCathFilesOpen;
  Begin
   with form1 do
    begin
     FileOpening(waveFilePath,'Open wave file, eg. "'+waveFilePath+'"','wav',label9,label54,label50);   //points to a file path wskazuje ścieżkę do pliku danych - waveFilePath
     showWaveHeadRecord(form1.canvas,SmallIntWaveFile,WaveCaption);
     extractFileDirAndFileName(fileDir,waveFileName,waveFilePath);                                        //find file suggestion for cathegory files
     cathFilePath:=fileDir+'\'+wavefileName+'.cath';
     FileOpening(cathFilePath,'Open cath type file, eg. "'+cathFilePath+'"','cath',Label3,label59,label43);
    end;{with}
    assignFile(cathFile,cathFilePath);
  End;{wavAndCathFilesOpen;}

 procedure AnalysesAndReportSaveFiles;
  Begin
    //------------------------------------------------where save file, Save spectrum analysis results
   extractFileDirAndFileName(fileDir,FileName,OutRecordFilePath);      //create fileDir from "OutRecordFilePath"  taken from the init file
   OutRecordFilePath:=fileDir+'\'+wavefileName+'.spc';
   form1.Label72.Caption:=OutRecordFilePath;
{1}  fileDateSize(OutRecordFilePath,tmp1,tmp2);     form1.label75.caption:=tmp1; form1.label74.caption:=tmp2;application.ProcessMessages; //directory from the Init file
  repeat
{2,save}  spcSave:=whereSave(OutRecordFilePath,'Save spectrum analysis results, into eg. "'+fileDir+'\'+FileName,'spc');  //spc
   if spcSave then
    begin
     form1.Label72.Caption:=OutRecordFilePath;
{3=1!}  fileDateSize(OutRecordFilePath,tmp1,tmp2);     form1.label75.caption:=tmp1; form1.label74.caption:=tmp2;application.ProcessMessages; //must be repeated, because the directory can changed
     try
      assignFile(outPutRecordFile,OutRecordFilePath);
      rewrite(outPutRecordFile);
     except
      showMessage('The file "'+OutRecordFilePath+'" could not be opened. There was something wrong with the path. Check it; or check init file text, i.e. "'+InitDir+'". Repiair or delete it');
      spcSave:=false;
     end;
    end{if spcSave}
   else
    if MessageDlg(pchar('[openFiles], Analysis results, i.e. "'+OutRecordFilePath+'" will not be saved!'#13#10+
       'You can retry or abort to continue with no saving. Remember, it is a must for the "WindowsSearch" procedure.'),
        mtWarning,[mbRetry,mbAbort],1)=3  //retry=4, abort=3 yes=6
    then break;
  until spcSave;
//------------------------------------------------where save file, Report
{4}  fileDateSize(ReportFilePath,tmp1,tmp2);        form1.label95.caption:=tmp1; form1.label94.caption:=tmp2;application.ProcessMessages;
     if spcSave then extractFileDirAndFileName(fileDir,FileName,OutRecordFilePath);      //create fileDir and fileName from "OutRecordFilePath"
     ReportFilePath:=fileDir+'\'+FileName+'Report.txt';
    repeat
{6,save} reportSave:=whereSave(ReportFilePath,'Save to report file slides and windows searching results into eg. "'+fileDir+'\'+fileName+'Report','txt');
     if reportSave then
       begin
        form1.label93.Caption:=ReportFilePath;
  {7=4} fileDateSize(ReportFilePath,tmp1,tmp2); form1.label95.caption:=tmp1; form1.label94.caption:=tmp2;application.ProcessMessages;
        assignFile(ReportFile,ReportFilePath);
        rewrite(ReportFile);
        writeln(ReportFile,#13#10,'Wave and cath data reading started at: ', FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
        writeln(ReportFile,'Results from "',application.ExeName,'" launching.');
        flush(ReportFile);
        form2.Button5.Enabled:=true; form2.Button10.Enabled:=true;
       end {if}
       else
       begin
        form2.Button5.Enabled:=false; form2.Button10.Enabled:=false;   //block slide and history saving
        if MessageDlg(pchar('[openFiles], Report file, i.e. "'+ReportFilePath+'" will not be created! Remember, it is a must for the WindowsSearch procedure.'#13#10+
           'You can retry or abort to continue with no saving.'),
           mtWarning,[mbRetry,mbAbort],1)=3   //retry=4, abort=3 yes=6
        then break;
       end;
    until reportSave;
  End;{AnalysesAndReportSaveFiles}

 procedure GaussWindowSearchingResultsSaveFile;
  Begin
   if windowsSearching then
     Begin
 {5}  fileDateSize(GaussSearchFilePath,tmp1,tmp2);   form1.label63.caption:=tmp1; form1.label62.caption:=tmp2;application.ProcessMessages;
      if spcSave then extractFileDirAndFileName(fileDir,FileName,OutRecordFilePath);      //create fileDir and fileName from "OutRecordFilePath"
      GaussSearchFilePath:=fileDir+'\'+FileName+'GaussSearch.txt';
      repeat
{8,save}  gausSave:=whereSave(GaussSearchFilePath,'Save gaussian windows searching results only into eg. "'+fileDir+'\'+fileName+'GaussSearch','txt');
       if gausSave then
        begin
  {9=5}  fileDateSize(GaussSearchFilePath,tmp1,tmp2); form1.label63.caption:=tmp1; form1.label62.caption:=tmp2;application.ProcessMessages;
         form1.label61.Caption:=GaussSearchFilePath;
         assignFile(GaussSearchFile,GaussSearchFilePath);
         rewrite(GaussSearchFile);
         writeln(GaussSearchFile,'Results of analysis of the Gauss weigts window');
         flush(GaussSearchFile);
        end{if}
       else
       if MessageDlg(pchar('[openFiles], Analysis results of the Gauss window search, i.e. "'+GaussSearchFilePath+'" will not be saved, it is a must for the'+
          ' WindowsSearch procedure.'#13#10'You can retry or abort to continue with no saving.'),
           mtWarning,[mbRetry,mbAbort],1)=3  //retry=4, abort=3 yes=6
        then break;
      until gausSave;
     End;{if windowsSearching}
  End;{ GaussWindowSearchingResultsSaveFile}

 procedure openFiles;

 //  var fileDir,FileName,waveFileName,path:pathStr;   //28112023, interface
  Begin  //  ===================  openFiles ======================
   Form1.PageControl3.ActivePageIndex:=4;
   wavAndCathFilesOpen;
   AnalysesAndReportSaveFiles;
   GaussWindowSearchingResultsSaveFile;
   form1.Label90.font.Color:=form1.Label48.font.Color;
   form1.Label90.Caption:='Click EXIT to start wave signal loading';
   if not writePathsToReport then showMessage('Could not write the "init" data to report file.'#13#10'Program error, debug whether the "reportFile" was opened or turn to the author');
  End;{openFiles}

 procedure introduction(out savedRec, prevSliceNbr,waveFileWinNbr:dword; out i0,i:longint);
  //some initial values
  var j,k:word;
  Begin
   if form1.RadioGroup2.ItemIndex=0 then modul:=modul_NpdBrms
   else modul:=filter_modul_NpdBrms;
   annotation:=true;
   savedRec:=0;personNr:=0;prevSliceNbr:=0;
   waveFileWinNbr:=(nbrOfData div jumpNbrSamples)*jumpNbrSamples; //only a whole number of portions can be analysed
   manager:=#1;   i0:=0;
   i:=fileSize(cathFile);          //debug
   form2.label11.caption:=intToStr(math.min(waveFileWinNbr,i));
   form2.label30.caption:=intToStr(nbrOfData div jumpNbrSamples);
   if form1.CheckBox3.Checked then maxFrameNbr:=maxFrameNbr0 else maxFrameNbr:=frameNbr; //form1.CheckBox3 - multiMean is on
   saveSlide:=false;
   for j:= 0 to count-1 do
    begin
     stepOutrecord.signal[j]:=0; stepOutrecord.weighedSignal[j]:=0; stepOutrecord.powerSpectr[j]:=0;
     stepOutrecord.slide_angle[j]:=0; stepOutrecord.vPSarr[j]:=0; stepOutrecord.cPSarr[0,j]:=0;
     stepOutrecord.smoothedSpectr[j]:=0; stepOutrecord.melSmoothSpectr[j]:=0;
     stepOutrecord.powerCepstr[j]:=0; stepOutrecord.vPCarr[j]:=0; stepOutrecord.cPCarr[j]:=0;
     stepOutrecord.melCepstr[j]:=0;
     for k:=0 to NbrOfMultiMean do stepOutrecord.cPSarr[k,j]:=0;
    end;
   with form2 do
    begin
     label7.top:=round(centr2-label7.height/1.5);
     label7.left:=panel2.left-6*canvas.font.Size;
     label7.Caption:='*1E-4';
    end;
  End;{introduction}

   label newStart;
   Begin //--------------------------------spectrAnalyser----------------------
    callChain:=callChain+'>spectrAnalyser';
    with form2 do
    with Panel9 do    //clearing, moving panel; "sponge"
     begin
      height:=panel1.height-2;        //corrected 01032024
      top:=panel1.top+1;
      width:=T0dashLength+2;
      left:=panel1.left+1;
      color:=clYellow;
      SendToBack;
      caption:='';
     end;
    panel2Stretch;  //09042024  (because changes of the check 82, 83 in the proc. "NormCheckStatesRestore" did not caused execution of their checkBoxClick methods)
    windowsSearching:=false;  form2.canvas.Pen.Color:=clWhite;{ f2Panel2Stretch:=high(smallInt); panel2Decimals:=0; 10122023}
    form2.panel1.Visible:=false;  form2.canvas.Rectangle(form2.panel1.Left-1,form2.panel1.Top-1,form2.panel1.Left+form2.panel1.Width+1,form2.panel1.Top+form2.panel1.Height+1);
    setLength(reIns,count);
    setLength(ImIns,count);
    setLength(angle,count);
    setLength(virt_vect,count); setLength(tmp_virt_vect,count);
    slidesRecordInit;
    computeFilter;//musi poprzedzać openFiles, aby obliczyć współczynniki skalujące wykresu filtru i zrobić sam wykres
    openFiles;
    form1.Show;
    rate:=WaveCaption.SampleRate;
    form1.Edit1.Text:=floatToStrF(rate,ffFixed,7,1);
    try
      osc_par(WaveCaption.SampleRate);
     except
      ShowMessage('Sample rate='+intTostr(WaveCaption.SampleRate)+'.'#13#10'You have probaly chosen improper wave file, program will be halted now');
      Halt;
    end;
    fft_par(form1.edit9,form2.Edit5);                  //Stałe parametry przetwarzania rFFT: y0, df, dOm, sin, cos, (windowWeights okien power2, firstIn, fidIx, cIdx, fcpstr)
    reset(cathFile);
    waveShow(form1.canvas,form1.Panel2 ,WaveCaption.dataBlockLength,SmallIntWaveFile);
    try
     setLength(speech,(WaveCaption.dataBlockLength+1) div 2+count);
    except
     ShowMessage('Could not assign memory to signal container. Probaly the signal is too long');
    end;{try}
    setLength(frameNbrArr,NbrOfMultiMean+1);
    setLength(frameNbr0Arr,NbrOfMultiMean+1);          // : array of integer;          //for multi CCR processing
    setLength(ringBuffChangePointArr,NbrOfMultiMean+1);// : array of integer;          //for multi CCR processing, change points on ring buffers
    setLength(reHistoryArr,NbrOfMultiMean+1);          // : array of Thistory;         //for multi CCR processing
    setLength(reMeanVectorArr,NbrOfMultiMean+1,count); // : array of array of double;
    multiMeanList;
    maxFrameNbr0:=0;
    for k:=0 to NbrOfMultiMean do if frameNbr0Arr[k]>maxFrameNbr0 then maxFrameNbr0:=frameNbr0Arr[k];
    Form1.Label90.Font.Color:=clYellow;
    Form1.Label90.Caption:='Signal samples are read, wait...';

    waveInput(SmallIntWaveFile,WaveCaption.dataBlockLength,nbrOfData,totalSignalStDev);     //****************************************

    Form1.Label90.Font.Color:=clGray;
    Form1.Label90.Caption:='Signal samples reading finished  at: '+ FormatDateTime('dd.mm.yyyy hh:nn:ss', Now);
    writeln(ReportFile,#13#10,'Wave and cath data reading finished at: ', FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
    form2.Edit24.Text:=form1.Edit24.Text;
    form2.Show;
    form1.Button4.Visible:=true;
    form1.Edit24.Text:=intToStr(frameNbr0);//bo frameNbr dostaje wartość z tekstu zadeklarowanego w form2edit24 na etapie projektu
    SaveCheckEnabler(false); //disable checkBoxes on the "Output" page
    setLength(reTmp,count); setLength(ImTmp,count);
    setLength(tmpArr,count);
    if form1.CheckBox6.Checked then count_cp:=cp else count_cp:=count;       //wyświetlać połowę liczby punktów
    OutCheckBoxesChecking;   //synchronises the "visual" output with the "start" one
    WhatToSave(true);
    FramesRepaint(count_cp,True);

    {----------------------------------======================Spectral analyses===================-------------------------------------------}
newStart:
    introduction(savedRec,prevSliceNbr,waveFileWinNbr,i0,i); //some initial values
    writeln(ReportFile,#13#10,'Spectral analyses started at: ', FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
 //TakePortions(out k:longWord; const nbrOfdata:dWord;reTmp,imTmp:TdbArr;out savedRec,prevSliceNbr,waveFileWinNbr:dword; out i0,i:longint; var annotation:boolean);
    standOnOff:=false;
    TakePortions(k,nbrOfData,reTmp,imTmp,savedRec,prevSliceNbr,waveFileWinNbr,i0,i,annotation,callChain);  //****************************************************************
    SaveCheckEnabler(true);
    form1.Button3.Enabled:=true;//odblokować możliwość ponownego uruchomienia programu
    if spcSave then seek(outPutRecordFile,0);
    PSrange:=80;  PSrange0:=80; form2.button19.Caption:= 'Reset '+intToStr(PSrange0); //restore PSrange when changed by augmentation buttons 13, 14
    checkBoxEnCode; // checkBoxEnCodeNbr:=checkBoxEnCode(cBc); //encode states of stream normalization czheckBoxes (82..92)
    WhatToSave(false);//AnalysisParamRegister(false);
    writeln(ReportFile,#13#10,'Spectral analyses finished at: ', FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
    flush(reportFile);
    if Form1.CheckBox60.Checked then  SuspendOrHibernate(True,False); //SetSuspendState(False, False, False);
    s:='';
    if not (spcSave or reportSave or GausSave) then s:='No analyses results were saved';
    if spcSave then s:=s+'"'+OutRecordFilePath+'" ';
    if reportSave then s:=s+#13#10'Analyses specifications you can find in'+' a file "'+ReportFilePath+'"';
    if GausSave then s:=s+#13#10'Gauss'' windows search results will be found in a file "'+GaussSearchFilePath+'"';
    showmessage('Analyses are finished.'#13#10'Find results of the analysis in '+s+#13#10'Ponowne uruchomienie nie jest możliwe, jeśli odsłuchiwano sygnał.'+
     #13#10'Jeśli okno wizualizacji jest pod spodem, to można powrócić do niego klikając przycisk "'+
     form1.Button4.Caption +'"'#13#10'lub pomniejszając bieżąco widoczne okno startowe górnym prawym przyciskiem'+
     ' systemowym okna');
    form1.CheckBox57.Enabled:=true;
    form1.RadioGroup7.Enabled:=true;
    form1.edit15.Enabled:=true;
    form1.edit16.Enabled:=true;
    NormCheckBoxesStatesToReport;
    if spcSave then closeFile(outPutRecordFile);
    if reportSave then closeFile(ReportFile);
    if gausSave and (TtextRec(GaussSearchFile).mode<>fmClosed) then closeFile(GaussSearchFile);
    if messageDlg('Click "Yes" if you like to start the analyses once more with the same data',mtConfirmation,[mbYes, mbNo],1)=mrYes then
     begin
      form2.checkbox61.Checked:=true;
      AnalysesAndReportSaveFiles;
      savedRec:=0;prevSliceNbr:=0; i0:=0;  manager:=#1; warning:=false;
      if form2.button4.CanFocus then  form2.button4.SetFocus; //"Next"
      goto newStart;
     end
     else
      begin
       setLength(imTmp,0);   finished:=true   //19022025 - in order to prevent erronous communication about errors on program finishing
      end;
   End; {spectrAnalyser}

 procedure windowsSearch(const nbrOfData:dword; annotation:boolean;callChain:string);
  type
   TcharSet=set of char;
   TDwordArr=array of dword;
   TCharByteArr=array[char] of byte;
  var pb1Wsp : single;
      emptyVal : dword;

 procedure bestPartCheckBoxes;
  Begin
   with form2 do
    begin
     checkbox9.checked:= True;  //PS
     checkbox32.checked:=True;  //PS
     checkbox10.checked:=false; //sPS
     checkbox33.checked:=false; //sPS
     checkbox11.checked:=false; //msPS visual
     checkbox34.checked:=false; //mPS output
     checkbox12.checked:=false; //vPS
     checkbox35.checked:=false; //vPS
     checkbox13.checked:=false; //cPS
     checkbox36.checked:=false; //cPS
     checkbox14.checked:=True;  //PC
     checkbox41.checked:=True;  //PC
     checkbox15.checked:=false; //mPC
     checkbox42.checked:=false; //mPC
     checkbox16.checked:=True;  //vPC   24032024
     checkbox43.checked:=true;  //vPC   23022024
     checkbox17.checked:=True;  //cPC   24032024
     checkbox44.checked:=True;  //cPC   24032024
     checkbox26.checked:=false; //aPS
     checkbox37.checked:=false; //aPS
     checkbox27.checked:=false; //avPS
     checkbox38.checked:=false; //avPS
     checkbox28.checked:=false; //acPS
     checkbox39.checked:=false; //acPS
     checkbox29.checked:=false; //aPC
     checkbox40.checked:=false; //aPC
     checkbox45.checked:=false; //mmcPS
     checkbox66.Checked:=true;  //Find T0
     checkBox75.visible:=True;  //show T0 in averaging process  24032024
     form1.checkbox49.checked:=false; //mmcPS
     form1.checkbox57.checked:=false; //save streams
    end;{with}
   try
    WhatToSave(true)
   except
    showMessage('Some error happened in te "WhatToSave" procedure called from the "bestPartCheckBoxes" procedure')
   end;
    manager:=#2;//09022024 because after bestPartCheckBoxes manager='R', what calls FramesRepaint clearing rectangle  //23022024 change manager:=#1 to #2
  End;{bestPartCheckBoxes}

  procedure WindowsSearchChecks;
  Begin
    writeln(ReportFile,'WindowsSearchChecks procedure. Started at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
   with form2 do
    begin
     checkbox9.checked:= True;  //PS
     checkbox32.checked:=True;  //PS
     checkbox10.checked:=false; //sPS
     checkbox33.checked:=false; //sPS
     checkbox11.checked:=false; //msPS visual
     checkbox34.checked:=false; //msPS  output
     checkbox12.checked:=True;  //vPS
     checkbox35.checked:=True;  //vPS
     checkbox13.checked:=True;  //cPS      24032024
     checkbox36.checked:=True;  //cPS      24032024
     checkbox14.checked:=True;  //PC
     checkbox41.checked:=True;  //PC
     checkbox15.checked:=false; //mPC
     checkbox42.checked:=false; //mPC
     checkbox16.checked:=True;  //vPC
     checkbox43.checked:=True;  //vPC
     checkbox17.checked:=true;  //cPC
     checkbox44.checked:=true;  //cPC
     checkbox26.checked:=false; //aPS
     checkbox37.checked:=false; //aPS
     checkbox27.checked:=false; //avPS
     checkbox38.checked:=false; //avPS
     checkbox28.checked:=false; //acPS
     checkbox39.checked:=false; //acPS
     checkbox29.checked:=false; //aPC
     checkbox40.checked:=false; //aPC
     checkbox45.checked:=false; //mmcPS
     checkbox66.Checked:=true;  //Find T0
     checkBox75.visible:=true;  //show T0 in averaging process
     form1.checkbox49.checked:=false; //mmcPS
     form1.checkbox57.checked:=false; //save streams
    end;{with}
   try
    WhatToSave(true)
   except
    showMessage('Some error happened in te "WhatToSave" procedure called from the "WindowsSearchChecks" procedure')
   end;
   writeln(ReportFile,'WindowsSearchChecks procedure. Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
  End;{WindowsSearchChecks}

 procedure FindAddresses(const nbrOfData:dword; out nbrOfPh,nbrOfPers,soundSetCount:byte; out selectedSoundsSet,persSet:TcharSet;
  out indexRegister:array of dword; out nbrOfSounds:dword; out phIdx,persIdx:TCharByteArr; out selSoundId:array of char);//TDwordArr);
  var
   k : dword;
   c : char;
   s : shortstring;

 procedure printAddressesList;
  var k:dword;
  Begin
   form2.CheckBox67.Enabled:=false;
   begin
    for k:=0 to nbrOfSounds do
     begin
      if k mod 20=0 then writeln(ReportFile);
      write(ReportFile,' ',k+1:6,indexRegister[k]:10);
     end;
    writeln(ReportFile);
   end;{print}
   form2.CheckBox67.Enabled:=true;
  End;{printAddressesList}

  Begin    //-----------------------------FindAddresses-------------------------------
  form2.ProgressBar1.Position:=0;  form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
  writeln(ReportFile,#10#13,form2.Label20.Caption);
  writeln(ReportFile,'FindAddresses procedure. Start at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
  selectedSoundsSet:=['i','y','e','a', 'o', 'u'];  nbrOfPh:=0;
   for c:=#0 to #255 do   //init indexes
    begin
     persIdx[c]:=high(persIdx[c]);
     if c in selectedSoundsSet then
      begin
       selSoundId[nbrOfPh]:=c;
       phIdx[c]:=nbrOfPh; inc(nbrOfPh)
      end
      else
       begin
        selSoundId[byte(c)]:=#255;
        phIdx[c]:=high(phIdx[c]);
       end;
    end;
   //------------find adresses of beginings of realizations of all sounds
   persSet:=[]; nbrOfPers:=0; soundSetCount:=0;
   for c:=#0 to #255 do
    if c in selectedSoundsSet then inc(soundSetCount);
   for k:=0 to high(indexRegister) do indexRegister[k]:=maxdword;
   pb1Wsp:=100/nbrOfData; //progress coefficient
   k:=0;  nbrOfSounds:=0; c:=#0;    reset(cathFile);    //(reset to ensure start from begining) reset zapewnia zawsze analize od początku niezależnie od wcześniejszych innych akcji
   while (not eof(cathFile)) and (k<=nbrOfData) do      //TCath=record phon,person,gender,buzHiss:char;age:byte; end;
    Begin
     if form2.Button12.Caption=butt12Caption then exit; //Windows search|Windows Search Break  (kliknięcie buttona strtujacego zatrzyma "badanie okien)
     read(cathFile,cath);
     if cath.TcPhon<>c then
      begin
       c:=cath.TcPhon;
       indexRegister[nbrOfSounds]:=k;         //register beginings of a sounds realizations
       inc(nbrOfSounds);                      //count all sounds (policz wszystkie dźwięki)
      end;{if}
     inc(k);
      if not (cath.TcPerson in persSet) then  //we assume, that each pers cathegory (not like the phon cathegory) embraces only one inseparable sequence of events
      begin
       include(persSet,cath.TcPerson);
       persIdx[cath.TcPerson]:=nbrOfPers;
       inc(nbrOfPers);                        //count all second cathegory  (i.e. "persons") values (policz osoby)
      end;
     form2.ProgressBar1.Position:=round(k*pb1Wsp);
     form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
     application.ProcessMessages;
    End;{while}
   indexRegister[nbrOfSounds]:=nbrOfData;     //nbrOfData, because the indexRegister should contain addresse of the end of last sound in order to point its center of realization (in case the last sound belongs to a selected sounds set)
   if Eof(cathFile) and (k<nbrOfData) then
    begin
     s:='Program error in procedure "SoundsIndexRegister"'#13#10'The "'+cathFilePath+
      '" reached end of file, but it was read '+intToStr(k)+' element instead of expected '+intToStr(nbrOfData)+
      ' elements';
     showMessage(s);
     writeln(ReportFile,s);
    end;
   write(ReportFile,'selectedSoundsSet: {');
   for c:=#0 to #255 do if c in selectedSoundsSet then write(ReportFile,c,', '); writeln(ReportFile,'}');
   write(ReportFile,'Person set: {');
   for c:=#0 to #255 do if c in persSet then write(ReportFile,c,', '); writeln(ReportFile,'}');
   writeln(ReportFile,'Found numbers of:'#13#10' sounds  cathegories values: phon  ',nbrOfSounds:7,#13#10' person':34,nbrOfPers:7);
   writeln(ReportFile, 'Sounds index register (contains also the uppest boundary of the last sound)');
   if form2.checkBox67.Checked then printAddressesList;
   writeln(ReportFile,'FindAddresses procedure. Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
   flush(ReportFile);
  End;{FindAddresses}

 procedure FindCenters(const nbrOfData:dword; const maxNbrOfEx:word; const nbrOfPh,nbrOfPers:byte;const nbrOfSounds:dword;
  out n:word; out lowerLimit,upperLimit,centrIdx : array of dword; const selectedSoundsSet,persSet:TcharSet;
  const indexRegister:TDwordArr; const phIdx,persIdx:TCharByteArr; const soundSetCount:byte; const selSoundId:array of char);
   var
     nbrOfExamples : array of array of word;
 nbrOfFullFilled,k : dword;
             cath1 : Tcath;

  procedure CentersPrint;
   var k:dword;
       i:byte;
   Begin
    writeln(ReportFile,'Number of examples ',n,', max number of examples for each selected sound ',maxNbrOfEx,'.');
    writeln(ReportFile,#13#10'Indexes of examples: begin, center, end of realization');
    form2.checkBox68.enabled:=false;
    if form2.checkBox68.Checked then
     begin
      if n>=20 then
      for k:=0 to n div 20-1 do
       begin
        write(ReportFile,'Beginings ');
        for i:=0 to 19 do write(ReportFile,' ',20*k+i+1:5,lowerLimit[20*k+i]:11);  writeln(ReportFile);
        write(ReportFile,'Centers   ');
        for i:=0 to 19 do  write(ReportFile,' ',20*k+i+1:5,centrIdx[20*k+i]:11);   writeln(ReportFile);
        write(ReportFile,'Ends      ');
        for i:=0 to 19 do  write(ReportFile,' ',20*k+i+1:5,upperLimit[20*k+i]:11); writeln(ReportFile,#13#10);
       end;
      flush(ReportFile);
      if n mod 20<>0 then//remainining part
       begin
        write(ReportFile,'Beginings ');
        for k:=20*(n div 20) to n-1 do write(ReportFile,k+1:4,lowerLimit[k]:10); writeln(ReportFile);
        write(ReportFile,'Centers   ');
        for k:=20*(n div 20) to n-1 do write(ReportFile,k+1:4,centrIdx[k]:10);   writeln(ReportFile);
        write(ReportFile,'Ends      ');
        for k:=20*(n div 20) to n-1 do write(ReportFile,k+1:4,upperLimit[k]:10); writeln(ReportFile,#13#10);
       end;{if mod}
       writeln(ReportFile,'Number of the "phon" cathegories ',intToStr(nbrOfPh),', number of the "person" cathegories ',intTostr(nbrOfPers),', number of full filled classes ',nbrOfFullFilled,'.');
       writeln(ReportFile,'Counts of collected examples of selected sounds (cathegory "phon") in cathegories "person"');
       for i:=0 to nbrOfPers-1 do {------------------histogram----------------------------}
        begin
         writeln(ReportFile,char(i+65));
         write(ReportFile,'  phon  '); for k:=0 to nbrOfPh-1 do  write(ReportFile,selSoundId[k]:6);                  writeln(ReportFile);
         write(ReportFile,'  count '); for k:=0 to nbrOfPh-1 do  write(ReportFile,nbrOfExamples[k,i]:6); writeln(ReportFile);
        end;{histogram}
     end;{print}
    flush(ReportFile);
    form2.checkBox68.enabled:=true;
   End;{CentersPrint}

  Begin
    //------------find centers of realizations of selected sounds
   writeln(ReportFile,#13#10,form2.Label20.Caption);
   writeln(ReportFile,'FindCenters procedure. Start at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
   setLength(nbrOfExamples,NbrOfPh,NbrOfPers);
   nbrOfFullFilled:=0; pb1Wsp:=100/nbrOfSounds;                                      //współczynnik postępu
   n:=0;  form2.ProgressBar1.Position:=0; form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';   Application.ProcessMessages;                                                                         //n - counter of examples adresses
   //for k:=nbrOfSounds-1 downto 0 do
   for k:=0 to nbrOfSounds-1 do
    begin
     if form2.Button12.Caption=butt12Caption then exit;  //Windows search|Windows Search Break  (kliknięcie buttona strtujacego zatrzyma "badanie okien)
     seek(cathFile,indexRegister[k]);
     read(cathFile,cath);
     if (not (cath.TcPhon in selectedSoundsSet)) or (not (cath.TcPerson in persSet))  then  continue;
     if nbrOfExamples[phIdx[cath.TcPhon],persIdx[cath.TcPerson]]>=maxNbrOfEx then continue;
     if nbrOfFullFilled>=soundSetCount*nbrOfPers then break;                                   //break searching when all examples were collected
     centrIdx[n]:=((indexRegister[k+1]-indexRegister[k]) div 2)+indexRegister[k];
     lowerLimit[n]:=indexRegister[k];
     upperLimit[n]:=indexRegister[k+1];
     if centrIdx[n]>=count div 2 then centrIdx[n]:=centrIdx[n]-count div 2;
     seek(cathFile,centrIdx[n]);                                                     //check if centrIdx still points to a proper sound
     read(cathFile,cath1);
     if cath1.TcPhon<>cath.TcPhon then continue;                                         //sound was too short
     inc(n);                                                                         //n - total number of examples
     inc(nbrOfExamples[phIdx[cath.TcPhon],persIdx[cath.TcPerson]]);
     if nbrOfExamples[phIdx[cath.TcPhon],persIdx[cath.TcPerson]]>=maxNbrOfEx then inc(nbrOfFullFilled);  //counts fullfilled cases
     form2.ProgressBar1.Position:=round((nbrOfSounds-1-k)*pb1Wsp);form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';   Application.ProcessMessages;
    end;{for}
    centersPrint;
    writeln(ReportFile,'FindCenters procedure. Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
  End;{FindCenters}


 procedure findBestPortions(const totNbrOfEx:dword;out centrIdx:array of dword; out bestPartCpstr:single;
                            out bestPartIdx:dword; const lowerLimit,centrIdx1,upperLimit:array of dword;out cathArr:array of Tcath;callChain:string);
 //-------------------------------------------------  Finding best portions in sounds -------------------
 var k,m,n,sliceNbr : dword;
          i,ibest,j : longInt;
          b1,b2,b21 : smallInt;
               cath : Tcath;
                  s : shortString;
          iBestHist : array of dword;

  Begin //------------------------- findBestPortions -------------------------------
   callChain:=callChain+'>findBestPortions';
   with form2,Panel9 do    //clearing, moving panel
    begin
     height:=panel1.height-4; //corrected 01032024
     top:=panel1.top+2
    end;
   form2.checkbox69.Enabled:=false; form2.checkbox70.Enabled:=false;
   writeln(ReportFile,#13#10,form2.Label20.Caption);
   writeln(ReportFile,'findBestPortions procedure.Start at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
   form2.RadioGroup7.ItemIndex:=0;  //Hanning's Window will be applied
   form2.RadioGroup3.ItemIndex:=0; form1.RadioGroup7.ItemIndex:=0; form1.RadioGroup3.ItemIndex:=0;
   s:=form2.RadioGroup7.Items[form2.RadioGroup7.ItemIndex];
   delete(s,pos('&',s),1);
   writeln(ReportFile,'The "',s,'" window was applied');
   bestPartCheckBoxes;
   form2.RadioGroup7.ItemIndex:=0; form2.RadioGroup3.ItemIndex:=0;   form1.RadioGroup7.ItemIndex:=0;  form1.RadioGroup3.ItemIndex:=0;
   s:=form2.edit10.Text;
  // form2.Label24.Caption:='Best part search point (of "'+s+'" range)'; blocked 20022024
   SearchLimits(b1,b2,form2.edit10);    //b1, b2 = lowerLimit, upperLimit
   setLength(iBestHist,b2-b1+1);
   for i:=b1 to b2 do

    try
     iBestHist[-b1+i]:=0;
    except
     showMessage('Error, index='+intToStr(-b1+i)+' exceedes high(iBestHist)='+intToStr(high(iBestHist)))
    end;
   if form2.checkBox69.Checked then
    begin
     writeln(ReportFile,'Explanatory notes:');
     writeln(ReportFile,'"ev. nbr k"          - order number corresponding to number of beginnings/centers/ends list');
     writeln(ReportFile,'"search idx"         - number of deviations from center of realisatios; one "deviation" is equal to ',intTostr(jumpNbrSamples), ' wave samples');
     if not form2.checkBox70.Checked then writeln(ReportFile,'"centr idx m"        - deviated addresse - begining of a portion');
     if not form2.checkBox70.Checked then writeln(ReportFile,'"period T0"          - currently found fundamental frequency period, it is an index connected with a maximum in cepstrum');
     writeln(ReportFile,'"best part idx"      - preserved addresse of a portion, where cepstrum reached the highest value.');
     if not form2.checkBox70.Checked then writeln(ReportFile,'"cepstr in T0 value" - a value reached by cepstrum in the T0 point');
     writeln(ReportFile,'"best cepstr. value" - a value reached by cepstrum in the best part of a sound being searched');
     if form2.CheckBox70.checked then b21:=b1-1 else b21:=b2;  //b1-1 in order to prevent print too long header  (04042014)
     if not form2.checkBox70.Checked then
      begin
       write(ReportFile,'-------');for i:=b1 to b21 do write(ReportFile,'---------------------------------------------'); write(ReportFile,'---------------------------');writeln(ReportFile,'-----------------');
       write(ReportFile,'   ev.|');for i:=b1 to b21 do write(ReportFile,'sea     centr  pe-      best   cepst   best |'); write(ReportFile,'sea  pe-      best    best|');writeln(ReportFile,'cathegories|':17);
       write(ReportFile,'   nbr|');for i:=b1 to b21 do write(ReportFile,'rch       idx riod      part   in T0 cepstr.|'); write(ReportFile,'rch riod      part cepstr.|');writeln(ReportFile,'ph':4,'per':4,'gen':4,'age|':5);
       write(ReportFile,'    k |');for i:=b1 to b21 do write(ReportFile,'idx         m   T0       idx   value   value|'); write(ReportFile,'idx   T0       idx   value|');writeln(ReportFile,'on':4,'son':4,'der':4,' |':5);
       write(ReportFile,'=======');for i:=b1 to b21 do write(ReportFile,'============================================='); write(ReportFile,'===========================');writeln(ReportFile,'=================');
      end
     else
      begin
       writeln(ReportFile,'---------------------------------------------------');
       writeln(ReportFile,'   ev.|sea  pe-      best    best|','cathegories|':17);
       writeln(ReportFile,'   nbr|rch riod      part cepstr.|','ph':4,'per':4,'gen':4,'age|':5);
       writeln(ReportFile,'    k |idx   T0       idx   value|','on':4,'son':4,'der':4,' |':5);
       writeln(ReportFile,'===================================================');
      end;
    end;{outprints}
   k:=0;  form2.ProgressBar1.Position:=0; form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
   prevHighBorder:=form2.Panel1.Left; pb1Wsp:=100/totNbrOfEx; //współczynnik postępu
   while k<totNbrOfEx do
    begin
     bestPartCpstr:=-maxSingle;      
     n:=centrIdx1[k];                                                     //here n gets its initial value; centrIdx1 was computed in "FindCenters" as centrIdx[n]:=centrIdx[n]-count div 2;
    // form2.panel1.Visible:=true;  //clear graph                         //block 05022024
    // form2.panel1.Visible:=false;
    //markSoundsBorders(const k:dword;lborderAddr,hborderAddr:int64;fontColor:longint;callChain:string);
     markSoundsBorders(k,lowerLimit[k],upperLimit[k],clolive,callChain);
     write(ReportFile,k:6,'|');
     i:=b1; bestPartIdx:=n;                                               //if a sound is so short that no analysis will be done then centrIdx[k] will keep its original value else it will receive new value
     form2.label52.Caption:='Current slice distan- ce from center of a sound [ms]';
     while i<=b2 do
      Begin
       if form2.Button12.Caption=butt12Caption then                       //analysis broken
        begin
         form2.edit10.Text:=s;
         exit;
        end;                                                              //Windows search|Windows Search Break button click (kliknięcie buttona startującego zatrzyma "badanie okien)
        if  GraphAgain then
         begin
          markSoundsBorders(k,lowerLimit[k],upperLimit[k],clgreen,callChain);
          GraphAgain:=false;
         end;
       j:=i*jumpNbrSamples;                                               //deviation; search with step of jumpNbrSamples (default=80 pts=5ms)
       form2.edit17.Text:=intToStr(i);  //
       if j+n>=0 then m:=j+n                                              //m - addresse of a begining of a portion; do not excess sounds bounds (nie przekraczać granic dźwięków!)
       else m:=0;
       if m<lowerLimit[k] then begin inc(i); continue end;                //had'nt step in a sound realization yet
       if m>upperLimit[k]-count then break;                               // upper bound of a sound exceed
       if not AnalysisPerformer(annotation,m,sliceNbr,0,callChain) then break;      //=false in phon description disagreement;
       if cpstrT0>bestPartCpstr then                                      //mark best part
        begin
         bestPartCpstr:=cpstrT0;
         bestPartIdx:=m;
         ibest:=i;
        end;
       if form2.checkBox69.Checked and not form2.checkBox70.Checked then                              //69: print the whole of the best findings process; 70: print only the "best" findings info
{wh}    write(ReportFile,i:3,m:10,T0:5,bestPartIdx:10,cpstrT0:8:0,bestPartCpstr:8:0,'|');   //so, print the whole best findings process;
       StepWiseManager(i,1,emptyVal);  //inc(i);
      End;{while i - search in sound for the best part addresse}
     centrIdx[k]:=bestPartIdx;     //centrIdx no longer contains addresses of  centers of sounds realizations;
     seek(cathFile,centrIdx[k]);
     read(cathFile,cath);
     cathArr[k]:=cath;
     inc(iBestHist[ibest-b1]);
     if form2.checkBox69.Checked  then                                                               {69: print the whole of the best findings process; "the best info" ma być dopisywana także na końcu ostatniego wiersza "pełnej" informacji}
{best}write(ReportFile,ibest:3,T0:5,bestPartIdx:10,bestPartCpstr:8:0,'|',cath.TcPhon:4,cath.TcPerson:4,cath.TcGender:4,cath.TcAge:4,'|');
     if form2.checkBox69.Checked then writeln(ReportFile);
     inc(k);
     form2.ProgressBar1.Position:=round(k*pb1Wsp);form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
    end;{while k; find best}
   form2.edit10.Text:=s;  form2.Label24.Caption:='Best part search range';
   if form2.checkBox69.Checked then
    begin
     write(ReportFile,'=======');for i:=b1 to b21 do write(ReportFile,'============================================='); write(ReportFile,'===========================');writeln(ReportFile,'=================');
    end;
   form2.checkbox69.Enabled:=true; form2.checkbox70.Enabled:=true;
   writeln(ReportFile,#13#10'Histogramm of the best portions addresses deviations');
   writeln(ReportFile,'nbr of deviation units from a sound center:  '); for i:=b1 to b2 do write(ReportFile,i:6);writeln(ReportFile);
   writeln(ReportFile,'count of observations:                       '); for i:=b1 to b2 do write(ReportFile,iBestHist[i-b1]:6);writeln(ReportFile);  //histogramm of best portions addresses deviations
   for k:=0 to k-1 do        //k=totNbrOfEx; control purpose
    begin
     seek(cathFile,centrIdx[k]);
     read(cathFile,cath);
     if (cathArr[k].TcPhon<>cath.TcPhon) or (cathArr[k].TcPerson<>cath.TcPerson) or (cathArr[k].TcGender<>cath.TcGender) or (cathArr[k].TcAge<>cath.TcAge) then
     showMessage('Procedure "findBestPortions", program error, cathegory discrepancy!');
    end;
   writeln(ReportFile,'findBestPortions procedure. Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
   flush(ReportFile);
   form2.checkbox69.Enabled:=true; form2.checkbox70.Enabled:=true;
    with form2, Panel9 do    //clearing, moving panel  "sponge"
     begin
      height:=panel1.height-2; //corrected 01032024
      top:=panel1.top+1;
      edit10.Enabled:=false;
     end;
  End;{findBestPortions}

   var
                       nbrOfPh,nbrOfPers,soundSetCount : byte;
                                                 g1,g2 : smallInt;
                       totNbrOfEx,gaussMaxIdx,GstDevIdx,
           GT0,GaussStdSpectIdxBest, GaussStdT0IdxBest : word;
sumGaussMaxIdx,sumGstDevIdx, skGaussMaxIdx,skGstDevIdx : extended;
                                               counter : dword;
             centrIdx1, centrIdx,lowerLimit,upperLimit : TdwordArr;
                                               cathArr : array of Tcath;
                             selectedSoundsSet,persSet : TcharSet;//set of char;
                                         indexRegister : TdwordArr;
                                                   i,j : longint;
                           nbrOfSounds,m,n,bestPartIdx : dword;
                                           {k,}wsCounter : longint;
                                         phIdx,persIdx : TCharByteArr;
                                            selSoundId : array[byte] of char;
      bestPartCpstr,gaussMax,GcpstrT0Fixed,GgaussStdev,
                                    GcpstrT0,GvPSstDev : single;
                                                  s,s1 : shortString;
// centrIdx[n] - register of example addresses
//lowerLimit, upperLimit bounds of sounds realizations
//n - total number of examples

 procedure parametersWriteDown(var outTextFile:textFile);
  Begin
  writeln(outTextFile,#13#10,FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
  writeln(outTextFile,'Analysed data',#13#10,Form1.label9.caption,#13#10,Form1.label3.caption);
  writeln(outTextFile,'Parameters');
  writeln(outTextFile,form2.label26.caption:34,'  ',form2.edit5.text);  //windows width
  writeln(outTextFile,form2.label35.caption:34,'  ',form2.edit7.text);  //rectangle filling
  writeln(outTextFile,form2.label71.caption:34,'  ',form2.edit2.text);  //cepstral lifter treshold
  writeln(outTextFile,form2.label92.caption:34,'  ',form2.edit24.text); //frame nbr in averaging
  writeln(outTextFile,form2.label22.caption:34,'  ',form2.edit8.text);  //nbr of sound examples
  writeln(outTextFile,form2.label23.caption:34,'  ',form2.edit9.text);  //range of Gauss windows searching
  writeln(outTextFile,form2.label24.caption:34,'  ',form2.edit10.text); //best part search range
  writeln(outTextFile,'Gauss standard deviation scaler ', intToStr(gaussScaler));
  End;{parametersWriteDown}

 procedure Header(var outTextFile:textFile);
 Begin
  writeln(outTextFile);
  writeln(outTextFile,form2.Label20.Caption,' Final results---------------------');
  writeln(ReportFile,'Start at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
  writeln(outTextFile);
  writeln(outTextFile,'Explanatory notes.');
  writeln(outTextFile,'gender values: W=woman, M=man, C=child'#13#10'age values: 1 -> 9-15 y., 2 -> 20-30 y., 3 -> 30-50 y., 4 -> 50-70 y.');
  writeln(outTextFile,'"window"                 - a weighting windows number');
  writeln(outTextFile,'"Gauss stdev"            - standard deviation of the gaussian curve or the same multiplied by ',intToStr(gaussScaler),', (gauss standard deviation index)');
  writeln(outTextFile,'"T0 curr"                - currently found fundamental period');
  writeln(outTextFile,'"T0 Fixd"                - the fundamental period found using the Hamming window');
  writeln(outTextFile,'"cpstr T0 Fixed|current" - cepstrum values at the T0 "Fixed|curr"');
  writeln(outTextFile,'"cpstrT0Fixed amplitude" - is a value in the current cepstrum obtained with a current weighting window applied, at the point "T0Fixd" found with the Hamming window');
  writeln(outTextFile,'"T0maxGaussIndex"        - gauss curve standard deviation index for the best gaussian curve,',
                #13#10'                           where the cepstrum takes maximum value over actually searched gaussian curves at the T0 fixed point;',
                #13#10'                           exactly it is the standard deviation coefficient for the Gauss curve',
                #13#10'Note. T0maxGaussIndex takes this GaussStDevIndex value from a considered set of cepstrum curves by which it reaches a higher value at the "T0 fixed" point, so it can differ from the GaussStDevIndex');
  writeln(outTextFile,'"vPSstDev value"         - standard deviation of a blind deconvoluted power spectrum; in case of the gaussian window this parameter at a standard deviation of this curve at a point point, where the "vPSstDev" takes the maximum value');
  writeln(outTextFile,'"vPSstDev max Gauss Idx" - index of the gaussian curve standard deviation, by which the vPSstDev takes the maximum value');

  writeln(outTextFile,#13#10'Full header names (for the "Excel" table):'#13#10,
  'Example ', 'addresse ',' ','phon',' ','person ','gender ','age ','window  ','windowsName  ','GaussStDevValue ','GaussStDevIndex ', 'T0currentIndex ','T0fixedIndex ',  'cpstr_T0fixedAmplitude ',  'cpstr_T0currentAmplitude ','vPSstDevValue ', 'vPSstDevMaxGaussIndex ','T0maxGaussIndex'#13#10);
  writeln(outTextFile,#13#10'-----------------------------------------------------------------------------------------------------------------------------------------');
  writeln(outTextFile,'Exam':5, 'add-':11,' ','ph':4,' ','per':4,' ','gen':4,' ','age':4,' ','win-':4,'  ','windows':15,'  ','Gauss':5,' ','Gauss':6,' ',  'T0':4,' ',  'T0':4,' ',  'cpstr_T0':10,' ',  'cpstr_T0':9,' ','vPSstDev':10,' ', 'vPSstDev':10,' ','T0':9);
  writeln(outTextFile, 'ple':5,'resse':11,' ','on':4,' ','son':4,' ','der':4,' ',  ' ':4,' ', 'dow':4,'  ',   'name':15,'  ','Stdev':5,' ','Stdev':6,' ','curr':4,' ','Fixd':4,' ',     'Fixed':10,' ',   'current':9,' ',   'value':10,' ','max_Gauss':10,' ','Max_gauss':9);
  writeln(outTextFile,   ' ':5,    ' ':11,' ', ' ':4,' ',  ' ':4,' ',  ' ':4,' ',  ' ':4,' ',   ' ':4,'  ',       '':15,'  ','value':5,' ','index':6,' ', 'idx':4,' ', 'idx':4,' ', 'amplitude':10,' ', 'amplitude':9,' ',       ' ':10,' ',      'Idx':10,' ','Idx':9);
  writeln(outTextFile,      '-----------------------------------------------------------------------------------------------------------------------------------------');
 End;{Header}

 function WSperformer(var forHeaderFile:text;const LastW:byte; const allWindows:boolean;callChain:string):boolean;
 //GaussStdSpectIdxBest, GaussStdT0IdxBest - best Gauss window standard deviation index for deconvoluted  spectrum and T0 adequately
  var i,j:word; k:longint;
  Begin   //----------------------------------WSperformer----------------------------------------
   callChain:=callChain+'>WSperformer';
   WindowsSearchChecks;
   T0sliceNbrGlob:=high(T0sliceNbrGlob);                  //13032024; high: 22032024
   writeln(ReportFile,'WSperformer procedure. Started at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
   result:=true;
   parametersWriteDown(forHeaderFile);
   Header(forHeaderFile);
   sumGaussMaxIdx:=0;sumGstDevIdx:=0; skGaussMaxIdx:=0; skGstDevIdx:=0; counter:=0;
   Form2.Edit9.Enabled:=false; manager:=#1;  //11032024
   pb1Wsp:=100/totNbrOfEx; //advance coefficient (współczynnik postępu)
   form2.ProgressBar1.Position:=0;form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
   form2.Label9.Caption:='Averaging Buffer position';  wsCounter:=0;
   form2.ProgressBar1.Position:=0; form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
   prevHighBorder:=form2.Panel1.Left; pb1Wsp:=100/totNbrOfEx; //współczynnik postępu
   k:=-1;  //27032024, if form2.CheckBox1.Checked then k:=-1 else k:=0;//17032024
   try
{4}while k<totNbrOfEx-1 do          //example's loop
    Begin {=========================================== WSperformer main loop ===========================================================}
     form2.panel1.Visible:=false;
     application.ProcessMessages;
     StepWiseManager(k,1,emptyVal); //increases k to chose next example from the the centrIdx list; the first value is = 1, but we need 0, so later we have to call centrIdx[k-1]
     fixT0:=true;  tempus:=k;
     markSoundsBorders(k,centrIdx[k]-frameNbr*jumpNbrSamples,centrIdx[k],clOlive,callChain);
     for j:=0 to LastW do                           //window's loop: 0 to 7 do
      begin
       form2.RadioGroup7.ItemIndex:=j;              //weighting windows radio -> manager:='t'
       form2.RadioGroup3.ItemIndex:=j; form1.RadioGroup7.ItemIndex:=j; form1.RadioGroup3.ItemIndex:=j;
       if j=1 then SearchLimits(g1,g2,form2.Edit9)  //range of Gauss windows searching
       else begin g1:=j; g2:=j; end;
       gaussMax:=-maxSingle; GvPSstDev:=-maxSingle;
       for i:=g1 to g2 do                           //Gauss windows loop
        if not allWindows or allWindows and ((i=GaussStdSpectIdxBest) or (i=GaussStdT0IdxBest) or (j<>1)) then  //check because of 2 version: Gauss windows search - the whole g1, g2 range will
        Begin                                                                                                  //be applied otherwise only that for the best T0 and for the best stDev will be applied
         if j=1 then form2.Edit4.Text:=intToStr(i);  application.processMessages;
         TimeBack:=true;                                  //is necessary in order to refresh averaging buffers because the weighting window was changed
         m:=centrIdx[k];
         n:=m;                                            //n is needed for compare time points when time back is performed; m=n means, that no time back is needed or that the action was performed
         if n=0 then showmessage('n=0!. WSperformer, Gauss window loop');                 //debug prp.
         if m>maxFrameNbr*jumpNbrSamples then dec(m,maxFrameNbr*jumpNbrSamples)
         else m:=m mod jumpNbrSamples;                    //cofnąć sie o tyle o ile możliwe zachowując synchronizację ze slajdami (mogłoby być m:=0)
         if (n>=jumpNbrSamples) then                       //nie łączyć warunków w jeden, aby nie powodować "integer overflow"  do not join conditions in order to avoid ineger overflow
          if (m<=n-jumpNbrSamples)  then                   //ze względu na inc(m, jumpNbrSamples )                              because of inc(m,jumpNbrSamples)
           repeat                                          //------------------------------averaging----------------------------------
            StepWiseManager(wsCounter,1,emptyVal);         //to turn on step mode at any moment of windows searching
            if form2.Button12.Caption=butt12Caption then   //Windows search|Windows Search Break  (kliknięcie buttona strtujacego zatrzyma "badanie okien)
             begin result:=false; exit end;                //goto broken;
            if timeBack then inc(m,jumpNbrSamples);
            form2.edit11.Text:=intToStr((n-m) div jumpNbrSamples);             //show current Averaging Buffer position
            if  GraphAgain then
             begin
              markSoundsBorders(k, centrIdx[k]-frameNbr*jumpNbrSamples,centrIdx[k],clGreen,callChain);
              GraphAgain:=false;
             end;
            //     AnalysisPerformer(var annotation:boolean; const iw:dword; var inpSliceNbr:dword; const savedRec:dword):boolean;
   {!}      if not AnalysisPerformer(annotation,m,n,m,callChain) then break;
           until timeBack=false                            //timeBack dostanie false w AnalysisPerformer, należy więc robić timeBack:=true także przy zmianie przykładu (chociaż nie koniecznie, bo to będzie wiazac się ze zmiana okna ważącego
          else timeBack:=false;{if (m<=n-jumpNbrSamples)}
         if j=1 then                                      //j=1 means, that a Gauss window was applied
          begin
          if cpstrT0Fixed>gaussMax then                   //find such a standard deviation of the Gauss curve by which cepstrum at T0Fixed takes the biggest value; T0Fixed - cepstrum value at a point T0 found with the Hamming window
           begin
            gaussMax:=cpstrT0Fixed;
            GcpstrT0Fixed:=cpstrT0Fixed;                  //=gaussMax!
            gaussMaxIdx:=i;                               //i - the standard deviation coefficient for the Gauss curve; gaussMaxIdx - identifier of the best standard deviation coefficient (now 1,=gaussMaxIdx<=200, see edit 9 text)
            GgaussStdev:=gaussStdev;                      //save in memory the actual gaussStdev value for later usage (printing to output)
            GT0:=T0;
            GcpstrT0:=cpstrT0;
           end;
           if GvPSstDev<vPSstDev then
            begin
             GvPSstDev:=vPSstDev;
             GstDevIdx:=i;                                //teraz to ma wskazywać index odch. stand. dla krzywej Gaussa
            end;
          end;
 //FinalPrints----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------;

         if j=1 then  {printsOut for Gauss window only (if j=1 then a gauss widow is applied)}
          begin
           s:=copy(Form2.RadioGroup7.Items[Form2.RadioGroup7.ItemIndex],0,15);
           delete(s,pos('&',s),1);
           if not allWindows then //do not print once more to the GaussSearchFile what is printed to the report file (ReportFile)
           writeln(GaussSearchFile,k:3,'  ',n:10,' ',cathArr[k].TcPhon:4,'',cathArr[k].TcPerson:4,' ',
           cathArr[k].TcGender:4,' ',cathArr[k].TcAge:4,' ',Form2.RadioGroup7.ItemIndex:4,' ',s:16,' ',   //copy(Form2.RadioGroup7.Items[Form2.RadioGroup7.ItemIndex],0,15)
           gaussStdev:7:3,' ',form2.Edit4.text:5,' ',T0:5,' ',T0Fixed:5,' ',cpstrT0Fixed:10:1,' ',cpstrT0:8:1,' ',
           vPSstDev:10:4,' ',GstDevIdx:10,' ',gaussMaxIdx:8);
           if allWindows then
            if (i=GaussStdSpectIdxBest) then  //GaussStdSpectIdxBest - best Gauss window standard deviation index for deconvoluted  spectrum
             begin
              s:=s+'StDevBest';
              writeln(ReportFile,k:4,'  ',n:10,' ',cathArr[k].TcPhon:4,'',cathArr[k].TcPerson:4,' ',cathArr[k].TcGender:4,' ',
              cathArr[k].TcAge:4,' ',Form2.RadioGroup7.ItemIndex:4,' ',s:16,' ',
              gaussStdev:6:3,' ',gaussMaxIdx:5,' ',T0:5,' ',T0Fixed:5,' ',cpstrT0Fixed:10:1,' ',cpstrT0:8:1,' ',vPSstDev:10:4,' ',GstDevIdx:10,' ','- ':8) //nowe poprawione
             end
            else
             begin
              s:=s+'T0best';
            writeln(ReportFile,k:4,'  ',n:10,' ',cathArr[k].TcPhon:4,'',cathArr[k].TcPerson:4,' ',cathArr[k].TcGender:4,' ',
            cathArr[k].TcAge:4,' ',Form2.RadioGroup7.ItemIndex:4,' ',s:16,' ',
            gaussStdev:6:3,' ',gaussMaxIdx:5,' ',T0:5,' ',T0Fixed:5,' ',cpstrT0Fixed:10:1,' ',cpstrT0:8:1,' ',vPSstDev:10:4,' ','-':10,' ',gaussMaxIdx:8)
             end;
          end;        {printsOut for Gauss window only}
        End;{for i, Gauss windows loop}
       s1:=form2.Edit4.text;
       if j=1 then                 //window=Gauss window
        begin
         gaussStdev:=GgaussStdev;
         s1:=intToStr(GstDevIdx);  //teraz to ma wskazywać index w krzywej Gaussa
         T0:=GT0;
         cpstrT0:=GcpstrT0;
         cpstrT0Fixed:=GcpstrT0Fixed;
         vPSstDev:=GvPSstDev;
         sumGaussMaxIdx:=sumGaussMaxIdx+gaussMaxIdx; skGaussMaxIdx:=skGaussMaxIdx+gaussMaxIdx*gaussMaxIdx;  //for T0
         sumGstDevIdx:=sumGstDevIdx+GstDevIdx; skGstDevIdx:=skGstDevIdx+GstDevIdx*GstDevIdx;                //for spectrum dynamics
         inc(counter);
         writeln(GaussSearchFile); //empty lines between examples
        end;
       if allWindows then
        begin
         s:=copy(Form2.RadioGroup7.Items[Form2.RadioGroup7.ItemIndex],0,15);
         delete(s,pos('&',s),1);
         writeln(ReportFile,k:4,'  ',n:10,' ',cathArr[k].TcPhon:4,'',cathArr[k].TcPerson:4,' ',
          cathArr[k].TcGender:4,' ',cathArr[k].TcAge:4,' ',Form2.RadioGroup7.ItemIndex:4,' ',s:16,' ','- ':6,' ',
          '- ':5,' ',T0:5,' ',T0Fixed:5,' ',cpstrT0Fixed:10:1,' ',cpstrT0:8:1,' ',vPSstDev:10:4,' ','-':10,'-':8);
        end;{if}
      end;{for j; window kind loop}
     form2.ProgressBar1.Position:=round(k*pb1Wsp);form2.Label15.Caption:=intToStr(form2.ProgressBar1.Position)+'%';
     if allWindows then writeln(ReportFile);  //empty line between examples
     flush(ReportFile);
    End;{while k, totNbrOfEx ======================================================================================}
    except
     showMessage('Some error happened in the while loop in the procedure WPperformer at k='+intToStr(k)+
     ' or tempus='+intTostr(tempus)+'Check, whether the "'+form2.label23.caption+'" contains proper, >0 values.'+
     'Check tharelly counting of totNbrOfEx (='+intToStr(totNbrOfEx)+'), and RAM allocation. Turn to the author');
    end;
   GaussStdT0IdxBest:=round(sumGaussMaxIdx/counter);                                                                   //for T0
   skGaussMaxIdx:=sqrt(skGaussMaxIdx/counter-(sumGaussMaxIdx/counter)*(sumGaussMaxIdx/counter));
   GaussStdSpectIdxBest:=round(sumGstDevIdx/counter);                                                                  //for spectrum dynamics
   skGstDevIdx:=sqrt(skGstDevIdx/counter-(sumGstDevIdx/counter)*(sumGstDevIdx/counter));
   writeln(ReportFile,'WSperformer procedure. Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now));
  End;{WSperformer}

 label broken,cont;
 var spcWin:shortint;  k:longint;
 Begin //--------------------------- windowsSearch --------------------       67,69,70
  if not (reportSave and gausSave and spcSave) then
   begin
    s:='[WindowsSearch] ';
    if not spcSave then s:=s+'Windows search can not be performed because you have not chosen a file for saving spectrum analyses results (*.spc).'#13#10;
    if not reportSave then s:=s+'Windows search can not be performed because you have not chosen file for saving report (*Report.txt).'#13#10;
    if not gausSave then s:=s+'Windows search can not be performed because you have not chosen file for saving gauss windows analyses results (*Gaus.txt).';
    ShowMessage(s+'Procedure will be exited now');
    exit
   end;
  form2.label20.Visible:=true;     form2.edit10.Enabled:=true; form2.checkBox24.Enabled:=false;
  form2.Label20.Caption:='Click e.g.'#13#10'"'+form2.Button4.Caption+'"'#13#10'or'#13#10+'"'+form2.checkbox2.Caption+'"'#13#10'to start searching';
  application.ProcessMessages; beep;
  k:=0;   emptyVal:=high(emptyVal); GaussStdSpectIdxBest:=count div 4; GaussStdT0IdxBest:=count div 2;  //prawdopodobne odchylenia standardowe najlepszych okien gaussowskich
  StepWiseManager(k,1,emptyVal);//stops the programm to give opportunity for checking options; emptyVal - normally needed for restarting analysis from scratch throught setting savedRec to 0; here without meaning
  spcWin:=form2.RadioGroup7.ItemIndex;
  if form2.CheckBox71.Checked then begin rewrite(ReportFile); rewrite(GaussSearchFile) end;
  writeln(ReportFile,'--------------------------- windowsSearch --------------------');
  form2.Edit8.Enabled:=false;
  form2.edit24.Text:=form2.edit11.Text;         //averaging range
  form2.edit11.Enabled:=false;                  //you can not change this parameter until the end of this procedure
  maxNbrOfEx:=strToInt(form2.Edit8.Text);
  writeln(ReportFile,'Results of searching for the best weighting window');
  windowsSearching:=form2.Button12.Caption=butt12Caption;
  setLength(indexRegister,nbrOfData div jumpNbrSamples +1);//round(nbrOfData/(strToInt(form2.edit12.Text)*rate/1000)));      //indexRegister registers addresses of sounds. Mean duration t (=edit12.text) contains t*rate/1000 wav samples, where t is in ms
  k:=high(indexRegister);
  form2.Button12.Caption:=butt12Caption+' Break';
  form2.Label20.Caption:='Windows Search - find adresses of selected sounds'#13#10'Wait'; application.ProcessMessages;
   beep;
{1}FindAddresses(nbrOfData,nbrOfPh,nbrOfPers,soundSetCount,selectedSoundsSet,persSet,indexRegister,nbrOfSounds,phIdx,persIdx,selSoundId);
  beep;
  if form2.Button12.Caption=butt12Caption then goto broken; //Windows search|Windows Search Break  (kliknięcie buttona strtujacego zatrzyma "badanie okien)
  setLength(centrIdx,maxNbrOfEx*soundSetCount*nbrOfPers);
  setLength(lowerLimit,maxNbrOfEx*soundSetCount*nbrOfPers);
  setLength(upperLimit,maxNbrOfEx*soundSetCount*nbrOfPers);
  setLength(centrIdx1,maxNbrOfEx*soundSetCount*nbrOfPers);
  setLength(cathArr,maxNbrOfEx*soundSetCount*nbrOfPers);
  m:=high(centrIdx[0]);
  for j:=0 to maxNbrOfEx*soundSetCount*nbrOfPers-1 do   //high init
   begin
    centrIdx[j]:=m; centrIdx1[j]:=m; lowerLimit[j]:=m; upperLimit[j]:=m;
   end;
  form2.Label20.Caption:='Windows Search - find adresses of centers of realizations of selected sounds'#13#10'Wait';   application.ProcessMessages;

{2}FindCenters(nbrOfData,maxNbrOfEx,nbrOfPh,nbrOfPers,nbrOfSounds,totNbrOfEx,lowerLimit,upperLimit,centrIdx1,
    selectedSoundsSet,persSet,indexRegister,phIdx,persIdx,soundSetCount,selSoundId);
  beep;
  with form2 do if button4.CanFocus then
  button4.SetFocus;
  if form2.Button12.Caption=butt12Caption then goto broken;
  form2.Label20.Caption:='Finding best portions in sounds'#13#10'Click e.g.'#13#10'"'+form2.Button4.Caption+
   '"'#13#10'or'#13#10+'"'+form2.checkbox2.Caption+'"'#13#10'to continue searching'; application.ProcessMessages;

{3}FindBestPortions(totNbrOfEx,centrIdx,bestPartCpstr,bestPartIdx,lowerLimit,centrIdx1,upperLimit,cathArr,callChain);  //centrIdx zawiera teraz adresy poczatków najlepszych wycinków
  beep;
  if form2.Button12.Caption=butt12Caption then goto broken;
  form2.Label20.Caption:='Windows Search Checks';   application.ProcessMessages;
{4} //function WSperformer(wFirst,wLast:byte; gaussSigmaSet:TlabelSet):boolean;
  form2.Label20.Caption:='Gauss Windows Search only'#13#10'Uncheck the "'+form2.checkBox2.Caption+'"'#13#10'Wait...';   application.ProcessMessages;
  if not WSperformer(GaussSearchFile,1,false,callChain) then goto broken; //Gauss windows searching only
  form2.Label20.Caption:='All Windows Search'#13#10'Wait';   application.ProcessMessages;
  Writeln(GaussSearchFile,'----------------------------------------------------------------------------------------------------------------------');
  writeln(GaussSearchFile,'Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now), '. There was ',wsCounter,' searched nbr of windows*nbr of examples');
  Writeln(ReportFile,'----------------------------------------------------------------------------------------------------------------------'#13#10,
                            'Item                                                                                   mean  standard dev. counter'#13#10,
                            '======================================================================================================================'#13#10,
                            'The best standard deviation of the Gauss window for sounds recognition               ',GaussStdSpectIdxBest:6,skGaussMaxIdx:14:3,counter:12,
                      #13#10'The best standard deviation of the Gauss window for fundamental period determination ',GaussStdT0IdxBest:6,skGstDevIdx:14:3,counter:12,
                      #13#10'----------------------------------------------------------------------------------------------------------------------'#13#10);
  if not WSperformer(ReportFile,7,true,callChain) then goto broken; //All windows searching and the gauss's for the best T0 and
  form2.Label9.Caption:='Nbr of frames in averaging';
  goto cont;
broken:
  showMessage(' Widows searching broken on demand; click once more the command "'+butt12Caption+'" to do it again from scratch');
cont:
  writeln(ReportFile,#13#10'-------------------------------------------------------------------------------------------------------------');
  if TTextRec( GaussSearchFile).mode<>fmClosed then
   begin
    writeln(GaussSearchFile,#13#10'-------------------------------------------------------------------------------------------------------------');
     flush(GaussSearchFile);
   end;
  form2.Button12.Caption:=butt12Caption;
  windowsSearching:=false;
  form2.Label20.Caption:='Windows Search finished, find results in the report, i.e. in "'+ReportFilePath+'"';
  writeln(ReportFile,form2.Label20.Caption);
  form2.Edit8.Enabled:=true; Form2.Edit9.Enabled:=true; form2.edit11.Enabled:=true; 
  writeln(ReportFile,'Finished at ',FormatDateTime('dd.mm.yyyy hh:nn:ss', Now), '. There was ',wsCounter,' searched nbr of windows*nbr of examples.');
  flush(ReportFile);
  form2.RadioGroup7.ItemIndex:=spcWin; form2.RadioGroup3.ItemIndex:=spcWin; form1.RadioGroup7.ItemIndex:=spcWin;
  form1.RadioGroup3.ItemIndex:=spcWin;
  beep;
  if Form1.CheckBox60.Checked then  SuspendOrHibernate(True,False);
  showMessage('Searching for optimal window finished. Find results in the report, i.e. in "'+ReportFilePath+'"'+
   #13#10'Check settings and continue with analyses');
  form2.CheckBox2.Checked:=true;
  form2.edit11.Text:=form2.edit24.Text;         //averaging range
  form2.checkBox75.visible:=false; //show T0 in averaging process
  form2.checkBox62.Enabled:=true;           //12032024
  if TTextRec(GaussSearchFile).mode<>fmClosed then
   begin
    flush(GaussSearchFile);
    closeFile(GaussSearchFile)
   end;
  form2.checkbox61.Enabled:=true;  form2.edit10.Enabled:=true;  form2.checkBox24.Enabled:=true;
 End;{windowsSearch}

Begin
 //defaults
 dataDir:=locDrv+'\apl\waver\WaverResults';
 OutRecordFilePath:=locDrv+'\apl\spectrum\SpectrResults\signal_spectra_and_cepstra.spc';
 ReportFilePath:=locDrv+'\apl\spectrum\SpectrResults\signal_spectra_and_cepstra_report.txt';
 GaussSearchFilePath:=locDrv+'\apl\spectrum\SpectrResults\signal_spectra_and_cepstra_GaussSearchResults.txt';
 cathFilePath:=dataDir+'\*.cath';
 waveFilePath :=dataDir+'\*.wav';
 rate:=16000;
 df:=62.5;
 count:=256;//high(count);01052025
 sqrCount:=high(sqrCount);
 phonSet:=[]; personSet:=[];  genderSet:=[];   ageSet:=[];
end.



25012025


         'E' : begin      //change in output streams, begin analysis from scratch
                ism:=0;   sWM_savedRec:=0;   prevSliceNbr:=0;
                Rewrite(outPutRecordFile);
                whatToSave(true);
                ShowMessage('Analyses will start from scratch!');
                manager:=#0; //'T';23102023
               end;
