## DEFINICE KONSTANT ##
# Délka krátkého segmentu řeči [ms] #
delka_okna = 10
# Min. intenzita v [-dB] vzhledem k maximu v nahrávce pro rozpoznanání samohlásky #
hranice_intenzity = 21

formant_koef = 4/5
f2f1_vaha = 0
f1_vaha = 1
f2_vaha = 1

pomer_hl_A_d = 1.8
pomer_hl_A_h = 2.5
pomer_hl_E_d = 2.2
pomer_hl_E_h = 3.6
pomer_hl_I_d = 4.5
pomer_hl_I_h = 10.0
pomer_hl_O_d = 1.7
pomer_hl_O_h = 2.5
pomer_hl_U_d = 1.85
pomer_hl_U_h = 3.5
         
f1_hl_A_d = 650
f1_hl_A_h = 750
f1_hl_E_d = 360
f1_hl_E_h = 650
f1_hl_I_d = 225
f1_hl_I_h = 460
f1_hl_O_d = 400
f1_hl_O_h = 580
f1_hl_U_d = 300         
f1_hl_U_h = 400

f2_hl_A_d = 1100
f2_hl_A_h = 1700
f2_hl_E_d = 1400
f2_hl_E_h = 1860
f2_hl_I_d = 1860
f2_hl_I_h = 2500
f2_hl_O_d = 820
f2_hl_O_h = 1300
f2_hl_U_d = 725
f2_hl_U_h = 1400

writeInfoLine: "Zahájen výkon skriptu na extrakci vybraných hlásek."
# Otevře dialogové okno pro načtení zdrojové řečové nahrávky
fileName$ = chooseReadFile$: "Zvolte zdrojovou nahrávku"
# Pokud nebylo zadáno jméno souboru, ukonči skript s chybovou hláškou
if fileName$ = ""
   exitScript: "Nezadali jste žádnou zdrojovou nahrávku,"
   ...+ " výkon skriptu byl zastaven!"
# V opačném případě načti soubor podle zadaného jména a cesty
else
   Read from file: fileName$
endif
# Do proměnné 'soundfile$' ulož jméno zpracovávaného souboru a vytvoří se kopie
soundfile$ = selected$("Sound")
# Ošetření vícekanálových nahrávek
Convert to mono
Rename: "temp"
select Sound 'soundfile$'
Remove
select Sound temp
Rename: soundfile$

# Zjištění údajů o nahrávce pro segmentaci
vzorkovaci_frekvence = Get sampling frequency
if vzorkovaci_frekvence < 16000
   exitScript: "Vzorkovací frekvence nahrávky je menší než 16 kHz. "
   ...+ "Pro extrakci souhlásek je zapotřebí akustická nahrávka "
   ...+ "se vzorkovací frekvencí 16 kHz nebo vyšší! "
   ...+ "Výkon skriptu byl zastaven!"
endif
pocet_vzorku = Get number of samples
pocet_segmentu = pocet_vzorku / (vzorkovaci_frekvence * delka_okna * 0.001)


# Výpočet průběhu F0 a formantů
To Pitch: 0.0, 75, 600
pitch = Get mean: 0, 0, "Hertz"
Remove
select Sound 'soundfile$'
To Pitch (ac): 0, 70, 15, "no", 0.03, 0.60, 0.01, 0.35, 0.14, pitch*1.8
pitch = Get mean: 0, 0, "Hertz"
select Sound 'soundfile$'
To Formant (burg): 0.0, 5, 6.25*pitch+4250, delka_okna*0.001, 50
select Sound 'soundfile$'
To TextGrid: "Hlasky", ""
Rename: "Hlasky"
select Sound 'soundfile$'


## Algoritmus pro určení čas. bodů, kde začínají samohlásky
## (c) Hugo Quené, May-June 2001, <Hugo.Quene@let.uu.nl>

# Samohláska je charakteristická lokálním maximem průběhu intenzity.
# Takové lokální maximum intenzity musí být aspoň -`hranice_intenzity` dB 
# vzhledem k maximální intenzitě nahrávky, aby bylo vyhodnoceno jako vhodné maximum.
# Poznámka: před určením přůběhu intenzity je nahrávka filtrována
# filtrem s parametry: C=1000, B=500 Hz.

# Okopírování původního Sound objektu do 'temp' (ochrana před převzorkováním originálu) 
Copy: "temp"

# Podvzorkování pokud f(vz) > 11025 Hz
if vzorkovaci_frekvence > 11025
   Resample: 11025, 1
   Rename: "temp"
endif

# Filtrace C=1000, B=500, útlum vysokých kmitočtů, zvýraznění hláskových formantů
Filter (one formant): 1000, 500

# Výpočet průběhu intenzity
# Minimální F0 je nastavena na dlouhé časové okno (doporučeno Paulem Boersma, autorem Praat, k omezení shimmeru)
# Vyhlazování přes 25 ms okno, další vyhlazování probíhá při výpočtu derivace
framelength = 0.01
To Intensity... 40 'framelength'
maxint = Get maximum... 0 0 Cubic
t1 = Get time from frame... 1

Down to Matrix
Rename... temp
endtime = Get highest x
ncol = Get number of columns
coldist = Get column distance

# Výpočet derivace přes okno délky 2h+1
h=1 
newt1 = 't1'+('h'*'framelength')
ncol = 'ncol'-(2*'h')
Create Matrix... intdot 0 'endtime' 'ncol' 'coldist' 'newt1' 1 1 1 1 1 (Matrix_temp[1,col+'h'+'h']-Matrix_temp[1,col]) / (2*'h'*dx)

# Převod derivace intenzity do zvukového objektu
To Sound (slice)... 1
Rename... temp_IntDot

# V derivaci průběhu intenzity se vybírají lokální maxima,
# která odpovídají nejstrmějším místům nárůstu intenzity;
# typicky tak nastává těsně před začátkem samohlásky
To PointProcess (extrema): 1, "yes", "no", "Sinc70"
Rename... temp_rises

select Sound temp_IntDot
# V derivaci průběhu intenzity najdi průchody nulou do záporných hodnot,
# které odpovídají lokálním maximům intenzity;
# typicky nastává v místě maximální amplitudy samohlásky
select Sound temp_IntDot
To PointProcess (zeroes): 1, "no", "yes"
Rename... temp_peaks

# Podle předpokladu, že začátek samohlásky se ve skutečnosti nachází uprostřed
# mezi těmito dvěma body se určí výsledné body:
select PointProcess temp_peaks
Copy... temp_onsets
Remove points between... 0 'endtime'

select PointProcess temp_peaks
npeaks = Get number of points
for pindex from 1 to npeaks
   select PointProcess temp_peaks
   ptime = Get time from index: pindex
   select Intensity temp_filt
   pint = Get value at time: ptime, "Nearest"
   if pint > (maxint-hranice_intenzity) and pindex > 1
      select PointProcess temp_rises
      rindex = Get low index: ptime
      rtime = Get time from index: rindex
      otime = ('rtime'+'ptime')/2
      select PointProcess temp_onsets
      Add point... 'otime'
   endif # pint>hranice_intenzity
endfor # pindex from 1 to npeaks

# Promazání dočasných objektů
select Sound temp
plus Intensity temp_filt
plus Matrix temp
plus Matrix intdot
plus Sound temp_IntDot
plus PointProcess temp_rises
plus PointProcess temp_peaks
Remove
select Sound temp
plus Sound temp_filt
Remove

# Přejmenování výsledného objektu PointProcess
select PointProcess temp_onsets
Rename... 'soundfile$'_onsets'hranice_intenzity'

## /Konec algoritmu pro určení čas. bodů, kde začínají samohlásky/




## Segmentace nahrávky na krátké úseky (v TextGridu), jejich pojmenování ##
select Sound 'soundfile$'
To TextGrid: "Segmenty", ""
for aktualni_segment from 1 to pocet_segmentu
   Insert boundary: 1, delka_okna * 0.001 * aktualni_segment
   Set interval text: 1, aktualni_segment, "p_" + string$(aktualni_segment)
endfor


# Vytvoření nové tabulky, sloužící jako výstup informací
Create Table with column names: "Hlasky", pocet_segmentu, "Pocatek Znelost F1 F2 F3 Hlaska1 Hlaska1koef Hlaska2 Hlaska2koef S Š Z Ž"


# Inicializace proměnných
for i from 1 to 4
   souhlaska[i]=0
endfor
samohlaska_potvrzena = 0
samohlaska_maximum = 0


## HLAVNÍ FUNKCE - ROZPOZNÁVÁNÍ HLÁSEK V JEDNOTLIVÝCH USECÍCH
# Analýza jednotlivých segmentů za sebou
for aktualni_segment from 1 to pocet_segmentu
   select Table Hlasky
     Set numeric value: aktualni_segment, "Pocatek", (aktualni_segment-1) * delka_okna * 0.001
   
   souhlaska = 0
   part_name$ = "p_" + string$(aktualni_segment)
   select TextGrid 'soundfile$'
   plus Sound 'soundfile$'
   Extract intervals where: 1, "no", "is equal to", part_name$
   vykon1 = Get intensity (dB)
   To Spectrum: "yes"
   LPC smoothing: 4 + (vzorkovaci_frekvence div 1000), 50
   
   # Srovnání energie ve frekvenčních pásmech pro rozpoznání vybraných samohlásek
   spektrum = Get band energy difference: 0, 1500, 3000, 8000
   if spektrum <> undefined and vykon1 > 50
   if (spektrum >= -12)
      spektrum1 = Get band energy difference: 0, 500, 900, 1400
      spektrum2 = Get band energy difference: 0, 500, 4500, 5000
      if (spektrum1 <= -16 and spektrum2 <= 2)
         spektrum = Get band energy difference: 2200, 3200, 3500, 6000
         if (spektrum <= 5)
            select Table Hlasky
            Set numeric value: aktualni_segment, "Ž", 1
            souhlaska = 1
         else
            select Table Hlasky
            Set numeric value: aktualni_segment, "Z", 1
            souhlaska = 1
         endif
      else
         spektrum = Get band energy difference: 750, 1500, 4500, 6000
         if (spektrum >= 7)
            spektrum = Get band energy difference: 2500, 3000, 4000, 6000
            if (spektrum <= 10)
               select Table Hlasky
               Set numeric value: aktualni_segment, "Š", 1
               souhlaska = 1
            else
               select Table Hlasky
               Set numeric value: aktualni_segment, "S", 1
               souhlaska = 1
            endif
         endif
      endif
   endif
   endif

   # Na základě údajů z předchozího cyklu se detekují vybrané samohlásky
   select Table Hlasky
   for i from 1 to 4
      if souhlaska
         label$ = Get column label: 9+i
         temp = Get value: aktualni_segment, label$
         if temp = 1
            souhlaska[i] += 1
            if (i mod 2) = 1
               souhlaska[i+1] += 0.5
            else
               souhlaska[i-1] += 0.5
            endif
            if souhlaska[i] >= 3 and samohlaska_potvrzena = 0
               select TextGrid Hlasky
               Insert boundary: 1, (aktualni_segment-3.999) * delka_okna * 0.001
               select Table Hlasky
               samohlaska_potvrzena = i
               samohlaska_maximum = souhlaska[i]
            elsif samohlaska_potvrzena = i and samohlaska_maximum < souhlaska[i]
               samohlaska_maximum = souhlaska[i]
            endif
         endif
      elsif souhlaska[i] > 0.5
         souhlaska[i] -= 1
      elsif souhlaska[i] = 0.5
         souhlaska[i] = 0
      endif
      if souhlaska[i]=0 and samohlaska_potvrzena = i
         select TextGrid Hlasky
         Insert boundary: 1, (aktualni_segment-samohlaska_maximum-1) * delka_okna * 0.001
         temp = Get interval at time: 1, (aktualni_segment-samohlaska_maximum-2) * delka_okna * 0.001
         if i = 1
            Set interval text: 1, temp, "s"
         elsif i = 2
            Set interval text: 1, temp, "š"
         elsif i = 3
            Set interval text: 1, temp, "z"
         elsif i = 4
            Set interval text: 1, temp, "ž"
         endif
         samohlaska_maximum = 0
         samohlaska_potvrzena = 0
      endif
   endfor
   
   # Promazání dočasných objektů
   part_name$ =  soundfile$ + "_p_" + string$(aktualni_segment) + "_1"
   select Sound 'part_name$'
   Remove
   select Spectrum 'part_name$'
   Remove
   select Spectrum 'part_name$'
   Remove



   select Pitch 'soundfile$'
   temp = Get value at time: (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"

   if temp <> undefined
      select Table Hlasky
        Set numeric value: aktualni_segment, "Znelost", 1

      select Formant 'soundfile$'
      f1 = Get value at time: 1, (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"
      f2 = Get value at time: 2, (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"
      f3 = Get value at time: 3, (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"
      b1 = Get bandwidth at time: 1, (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"
      b2 = Get bandwidth at time: 2, (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"
      b3 = Get bandwidth at time: 3, (aktualni_segment-0.5) * delka_okna * 0.001, "Hertz", "Linear"
      
      if f1 <> undefined and f2 <> undefined and f3 <> undefined and b1 <> undefined and b2 <> undefined and b3 <> undefined
         select Table Hlasky
           Set numeric value: aktualni_segment, "F1", f1
           Set numeric value: aktualni_segment, "F2", f2
           Set numeric value: aktualni_segment, "F3", f3

         hl_A = 0
         hl_E = 0
         hl_I = 0
         hl_O = 0
         hl_U = 0

         procedure analyzujFormanty: .f_parametr, .fd, .fh, .vaha, .samohlaska
             .hl_X = 0
             if (.f_parametr < .fd)
                .hl_X += (.f_parametr / .fd - formant_koef)*(.vaha/(1-formant_koef))
             elsif (.f_parametr > .fh)
                .hl_X += (.f_parametr / .fh - 1/formant_koef)*(.vaha/(1-1/formant_koef))
             else
                .hl_X += .vaha
             endif
             if .samohlaska = 1
                hl_A += .hl_X
             elsif .samohlaska = 2
                hl_E += .hl_X
             elsif .samohlaska = 3
                hl_I += .hl_X
             elsif .samohlaska = 4
                hl_O += .hl_X
             elsif .samohlaska = 5
                hl_U += .hl_X
             endif
         endproc
        @analyzujFormanty: f2/f1, pomer_hl_A_d, pomer_hl_A_h, f2f1_vaha, 1
        @analyzujFormanty: f2/f1, pomer_hl_E_d, pomer_hl_E_h, f2f1_vaha, 2
        @analyzujFormanty: f2/f1, pomer_hl_I_d, pomer_hl_I_h, f2f1_vaha, 3
        @analyzujFormanty: f2/f1, pomer_hl_O_d, pomer_hl_O_h, f2f1_vaha, 4
        @analyzujFormanty: f2/f1, pomer_hl_U_d, pomer_hl_U_h, f2f1_vaha, 5

        @analyzujFormanty: f1, f1_hl_A_d, f1_hl_A_h, f1_vaha, 1
        @analyzujFormanty: f1, f1_hl_E_d, f1_hl_E_h, f1_vaha, 2
        @analyzujFormanty: f1, f1_hl_I_d, f1_hl_I_h, f1_vaha, 3
        @analyzujFormanty: f1, f1_hl_O_d, f1_hl_O_h, f1_vaha, 4
        @analyzujFormanty: f1, f1_hl_U_d, f1_hl_U_h, f1_vaha, 5

        @analyzujFormanty: f2, f2_hl_A_d, f2_hl_A_h, f2_vaha, 1
        @analyzujFormanty: f2, f2_hl_E_d, f2_hl_E_h, f2_vaha, 2
        @analyzujFormanty: f2, f2_hl_I_d, f2_hl_I_h, f2_vaha, 3
        @analyzujFormanty: f2, f2_hl_O_d, f2_hl_O_h, f2_vaha, 4
        @analyzujFormanty: f2, f2_hl_U_d, f2_hl_U_h, f2_vaha, 5


         hl[1] = hl_A
         hl[2] = hl_E
         hl[3] = hl_I
         hl[4] = hl_O
         hl[5] = hl_U
         for i from 1 to 5
            hlaska[i] = i
         endfor      
         for i from 1 to 5
            temp1 = hl[i]
            temp2 = hlaska[i]
            j = i-1
            while (j >= 1) and (hl[j] > temp1)
               hl[j+1] = hl[j]
               hlaska[j+1] = hlaska[j]
               j = j-1
            endwhile
            hl[j+1] = temp1
            hlaska[j+1] = temp2
         endfor

         
         select Table Hlasky
         # A=1, E=2, I=3, O=4, U=5
           Set numeric value: aktualni_segment, "Hlaska1", hlaska[5]
           Set numeric value: aktualni_segment, "Hlaska2", hlaska[4]
           Set numeric value: aktualni_segment, "Hlaska1koef", hl[5]
           Set numeric value: aktualni_segment, "Hlaska2koef", hl[4]

      endif
   else
      select Table Hlasky
        Set numeric value: aktualni_segment, "Znelost", 0
   endif
endfor




## ALGORITMUS NA URČENÍ SAMOHLÁSEK ZE ZJIŠTĚNÝCH ÚDAJŮ
part_name$ = soundfile$ + "_onsets" + string$(hranice_intenzity)
select PointProcess 'part_name$'
# Zjištění počtu samohlásek podle výsledku dřívějšího algoritmu
pocet_samohlasek = Get number of points

for aktualni_samohlaska from 1 to pocet_samohlasek
   select PointProcess 'part_name$'
   # Zjištění času nástupu aktuální samohlásky
   pocatek = Get time from index: aktualni_samohlaska

   select Sound 'soundfile$'
   vykon1 = Get power: pocatek, pocatek + (delka_okna * 0.001)
   select Table Hlasky
   for i from 1 to 5
      hl[i] = 0
   endfor

   # Cyklus pro určení konkrétní samohlásky
   for i from 2 to 6
      select Sound 'soundfile$'
      vykon2 = Get power: pocatek + ((i-1) * delka_okna * 0.001), pocatek + ((i) * delka_okna * 0.001)
      select Table Hlasky
      if (vykon1 <= vykon2*1.2)
         hlaska[1] = Get value: (pocatek) div (delka_okna * 0.001) + i, "Hlaska1"
         hlaska[2] = Get value: (pocatek) div (delka_okna * 0.001) + i, "Hlaska2"
         hlaska[3] = Get value: (pocatek) div (delka_okna * 0.001) + i, "Hlaska1koef"
         hlaska[4] = Get value: (pocatek) div (delka_okna * 0.001) + i, "Hlaska2koef"
         if hlaska[1] <> undefined
            hl[hlaska[1]] += hlaska[3] * 1.25
            hl[hlaska[2]] += hlaska[4]
         endif
      endif
   endfor

   for i from 1 to 5
      hlaska[i] = i
   endfor     

   # Vyhodnocení konkrétní samohlásky (seřazení podle příznaků)
   for i from 1 to 5
      temp1 = hl[i]
      temp2 = hlaska[i]
      j = i-1
      while (j >= 1) and (hl[j] > temp1)
         hl[j+1] = hl[j]
         hlaska[j+1] = hlaska[j]
         j = j-1
      endwhile
      hl[j+1] = temp1
      hlaska[j+1] = temp2
   endfor

   # Určení konce samohlásky
   temp = 0
   temp1 = 3
   vykon2 = 1
   while (temp1 >= 3) and (vykon1 <= vykon2*1.2)
      temp += 1
      temp1 = 0
      for i from 1 to 6
         select Table Hlasky
         temp2 = Get value: (pocatek) div (delka_okna * 0.001) + i + temp, "Hlaska1"
         if (temp2 = hlaska[5])
            temp1 += 1
         else
            temp2 = Get value: (pocatek) div (delka_okna * 0.001) + i + temp, "Hlaska2"
            if (temp2 = hlaska[5])
               temp1 += 0.5
            endif
         endif
      endfor
      select Sound 'soundfile$'
      vykon2 = Get power: pocatek + ((temp + 2) * delka_okna * 0.001), pocatek + ((temp + 3) * delka_okna * 0.001)
   endwhile

   select TextGrid Hlasky
   Insert boundary: 1, pocatek
   pocatek = ((pocatek) div (delka_okna * 0.001)) / 100
   kontrola = Get interval at time: 1, pocatek + (temp + 2.98) * (delka_okna * 0.001)
   kontrola = Get end point: 1, kontrola
   if pocatek + (temp + 2.99) * (delka_okna * 0.001) <> kontrola
      Insert boundary: 1, pocatek + (temp + 2.99) * (delka_okna * 0.001)
   endif
   temp = Get interval at time: 1, pocatek + (temp + 2.98) * (delka_okna * 0.001)
   
   if hlaska[5] = 1
      Set interval text: 1, temp, "a"
   elsif hlaska[5] = 2
      Set interval text: 1, temp, "e"
   elsif hlaska[5] = 3
      Set interval text: 1, temp, "i"
   elsif hlaska[5] = 4
      Set interval text: 1, temp, "o"
   elsif hlaska[5] = 5
      Set interval text: 1, temp, "u"
   endif
endfor


# Vytvoření zvukové objektu obsahující 10 ms ticha (mezi hlásky)
Create Sound from formula: "ticho", 1, 0.0, 0.01, vzorkovaci_frekvence, "0"

## Určení adresáře, do kterého se uloží výstupní soubory
directoryName$ = chooseDirectory$: "Zvolte cílový adresář pro uložení výstupních souborů"
if directoryName$ = ""
   appendInfoLine: "CHYBA! Nezadali jste žádný cílový adresář a skript se proto nedokončil."
   appendInfoLine: "Pro extrakci bude nutné spustit skript znovu."
   exitScript: "Nezadali jste žádný cílový adresář,"
   ...+ " výkon skriptu byl zastaven!"
else
   appendInfoLine: "Extrahované samohlásky budou uloženy do adresáře:"
   appendInfoLine: directoryName$ + "/"
   appendInfoLine: ""
endif

## Funkce, která extrahuje jednotlivé hlásky z TextGrid Hlasky,
## kategorizuje je, poskládá do záznamu za sebe s mezerou 10 ms
## a uloží do výstupního souboru zadáného výše
appendInfoLine: "Počty extrahovaných hlásek:"

procedure extrahujHlasku: .hlaska$
   select TextGrid Hlasky
   plus Sound 'soundfile$'
   Extract intervals where: 1, "no", "is equal to", .hlaska$
   kontrola$ = selected$("Sound")
   if kontrola$ <> soundfile$
      temp = numberOfSelected ("Sound")
   else
      temp = 0
   endif
   appendInfoLine: "/" + .hlaska$ + "/: " + string$(temp)

   # Pokud byla zjištěna žádaná hláska, provede se její extrakce
   if temp > 0
      # K jednotlivým hláskám se připojí 10 ms ticha a pospojují se k sobě
      for i from 2 to temp
         part_name$ = soundfile$ + "_" + .hlaska$ + "_" + string$(i)
         select Sound 'part_name$'
         plus Sound ticho
         Concatenate
         part_name$ = .hlaska$ + "_" + string$(i)
         Rename: part_name$
      endfor

      part_name$ = soundfile$ + "_" + .hlaska$ + "_" + string$(1)
      select Sound 'part_name$'
      for i from 2 to temp
         part_name$ = .hlaska$ + "_" + string$(i)
         plus Sound 'part_name$'
      endfor

      Concatenate
      Rename: "Hláska_" + .hlaska$

      # Promazání pomocných objektů
      for i from 1 to temp
         part_name$ = soundfile$ + "_" + .hlaska$ + "_" + string$(i)
         select Sound 'part_name$'
         Remove
      endfor

      for i from 2 to temp
         part_name$ = .hlaska$ + "_" + string$(i)
         select Sound 'part_name$'
         Remove
      endfor

      # Uložení WAV souboru do zadaného adresáře
      part_name$ = "Hláska_" + .hlaska$
      select Sound 'part_name$'
      Save as WAV file: directoryName$ + "/Hláska_" + .hlaska$ + ".wav"
   endif
endproc

@extrahujHlasku: "a"
@extrahujHlasku: "e"
@extrahujHlasku: "i"
@extrahujHlasku: "o"
@extrahujHlasku: "u"
@extrahujHlasku: "s"
@extrahujHlasku: "š"
@extrahujHlasku: "z"
@extrahujHlasku: "ž"

select Sound ticho
# plus Table Hlasky
# plus TextGrid 'soundfile$'
# part_name$ = soundfile$ + "_onsets" + string$(hranice_intenzity)
# plus PointProcess 'part_name$'
# plus TextGrid Hlasky
plus Formant 'soundfile$'
plus Pitch 'soundfile$'
Remove