Peatükk 19 Praati skriptid

Skriptiga on võimalik koguda ühte tekstifaili kokku erinevad käsud ja neid kombineerida või korrata. Nii on võimalik teha oma tööd palju lihtsamaks. Algajale skriptikirjutajale ei pruugi küll see lihtne näida ning väiksema andmestiku korral võib tunduda, et lihtsam on mõõtmisedandmed koguda toimetamisaknast käsitsi väärtuseid tabelisse kirjutades. Skripti kirjutamine on kindlasti intellektuaalselt huvitavam kui numbrite mehaaniline ümber kirjutamine ning suurema andmestiku korral tasub ettevõetud vaev end kuhjaga ära.

Praatil on täiemahuline skriptikeel. Kõik käsud, mis on Praati graafilise kasutajaliidese menüüdes, töötavad sama moodi ka skriptides. Tänu sellele on Praat hea keel, millega päris algaja skriptimist õppida: saame protseduuri teha läbi graafilise kaustajaliidese kaudu ja seejärel kasutatud käsud skripti suunata. Kui skripti kirjutades ei tule mõni käsk või selle argumendid meelde, saab graafilisest menüüst järgi vaadata. Aga lisaks käskudele on skriptidega võimalik määrata muutujaid, teha tsükleid ja palju muud.

19.1 Esimene skript

Ava uus skriptieditori aken: menüü Praat > New Praat script. Avanenud aknasse hakkamegi skripti kirjutama.

Vali menüüst Edit > Clear history. Praat peab meeles, mida sa oled parasjagu käimas oleva sessiooni jooksul teinud ja Clear history kustutab selle mälust ära ja hakkab käske koguma uuesti sellest hetkest alates.

Nüüd mine objektiaknasse, vali mõni Sound objekt, joonista see pildiaknasse ilma viimistlemata (st võta ära linnuke kastist Garnish) ja viimistle ise (st lisa Praati pildiakna menüüs leiduvate käskudega skaalad ja telgede pealkirjad jms).

Kui joonis valmis, siis mine avatud skriptieditori, vali menüüst Edit > Paste History. Nüüd ongi sul olemas skript, mis valib objektiaknast selle objekti ja teeb sellest joonise.See tekst, mis skriptieditoris on, ongi skript: käskude kogum, mida saab tekstina toimetada ja uuesti jooksutada.

Et proovida, kas skript töötab, mine pildiaknasse ja kustuta kõik ära (Edit > Erase all) ja seejärel jooksuta skripti: mine skriptieditori ja vali käsk Run > Run (või Ctrl-r).

Edasi võiks seda skripti kohendada nii, et see töötaks ka teiste sama tüüpi objektidega või näiteks käiks läbi kõik objektiaknas olevad objektid ja teeks igast ühest joonise.

19.2 Käsud ja argumendid

Kõik käsud Praati menüüdes on samal kujul kasutatavad Praati skriptides. Praati käsud järgivad loogikat, et kui käsule järgneb dialoogiaken, kus küsitakse mingeid parameetreid, siis menüüs lõppeb käsk kolme punktiga (nt Draw...), kui dialoogiakent pole, siis pole ka kolme punkti (Erase all). Skriptis asendab kolme punkti koolon. Seega kui käsk ei eelda mingite parameetrite täpsustamist, võib selle skripti kirjutada täpselt sellisel kujul nagu ta on, nt järgnev käsk skriptis kustutab pildiaknast ära kõik, mis seal oli:

Erase all

Kui käsk eeldab parameetrite täpsustamist, siis kõik, mida dialoogiaknas küsitakse, järgnevad skriptis koolonile ja eristatakse komadega. Skriptimisel nimetatakse käsu küsitavaid parameetreid argumentideks. Nt kui teha Sound objektist Pitch objekt, küsitakse kolme argumenti: analüüsi sammu (vaikimisiväärtus 0 tähendab, et samm võetakse automaatselt) ja põhitooni piire (min 75 Hz ja max 600 Hz). Skriptis oleks sama käsk selline:

To pitch: 0, 75, 600

Neis kohtades, kus dialoogiaknas on linnuke (nt Draw... käsul Garnish), märgib linnukest “yes” või 1 ja linnukese puudumist “no” või 0. Tekstina antud argumendid peavad olema jutumärkides. (NB! Jutumärgid peavad olema sirged, ", mitte stiliseeritud “algavad-lõppevad” jutumärgid. Kui kopeerid siit tekstist, siis kontrolli, et kogemata ei oleks siinse õpiku toimetamise käigus tekstiredaktor neid muutnud, muidu saad veateateid.)

Näiteks Sound objekti käsk Draw... oleks skriptis kirjas nii (ütleme, et tahaks joonistada 0-3 sekundit, amplituudiulatus oleks valitud automaatselt, joonist ei viimistleta ja joonistatakse lainekõverana):

Draw: 0, 3, 0, 0, "no", "Curve"

Praati skriptis peab iga käsk olema eraldi real. Kui tunned mõnd muud tavalisemat skripikeelt (R, Python, Unix), siis see Praati eripära võib olla piirav, aga Praati käske kombineerida ja üksteise sisse panna ei saa.

Samas üks käsk peab olema ühel real. Juhul, kui käsurida läheb väga-väga pikaks, siis saab ka käsku mitme rea peale jagada. Siis peab iga järgnev rida, kus käsk jätkub, algab kolme punktiga, nt:

To pitch: 0,
... 75, 600

Järgnevates peatükkides on seda võimalust kasutatud, et tekst veerule ära mahuks. Kui neid näiteid Praati skriptiaknas katsetad, siis võid käsud ühes reas kirjutada.

19.3 Muutujad

Skriptis saab määrata muutujaid ja anda neile väärtusi. Muutuja on “x”, millel on kindel funktsioon, aga väärtus võib muutuda (või nagu “a” tähistab ruudu külje pikkust ruudu ümbermõõdu valemis P=4a).

a = 5
tulemus = 4*a
writeInfo: "Ruudu ümbermõõt on ", tulemus, "."

Muutujatel peavad olema nimed, mis ei algaks suure algustähe või numbriga (muidu võivad suuri tähti ja numbreid sisaldada küll), ei sisaldaks täpitähti ega tühikuid. Suure algustähega algavad skriptis ainult käsud ja muutujad ei tohi nendega sassi minna.

Muutujaid on kahte sorti: sõnalised ja arvulised. Erinevalt R-i skriptikeelest ja sarnaselt Pythonile peab Praatis sõnalistel ja numbrilistel väärtustel selget vahet tegema. Sõnaliste muutujate nimed lõppevad Praatis dollarimärgiga ($).

a = 5
tulemus = 4*a
vastus$ = "Ruudu ümbermõõt on "
yhik$ = "cm"
writeInfo: vastus$, tulemus, yhik$

19.3.1 Arvuline muutuja

Arvuliste muutujatega saab matemaatilisi tehteid teha.

Proovi, mis juhtub, kui jooksutad sellist skripti:

muutuja1 = 5
muutuja2 = 7
muutuja3 = muutuja2 - muutuja1
muutuja4 = muutuja3 * muutuja1
writeInfoLine: "(", muutuja2, " - ", 
... muutuja1, ") * ", muutuja1, " = ", muutuja4

Proovi, mis juhtub, kui mõne muutuja väärtust muudad?

Viimasel real on käsk writeInfoLine, millele järgnev tekst kuvatakse infoaknasse tekstina. Kui teksti sees on mõni muutuja, siis see asendatakse selle muutuja väärtusega.

Juba olemasolevale muutujale saab teha tehteid ilma uute muutujateta:

muutuja = 3
writeInfoLine: muutuja
muutuja += 3
appendInfoLine: muutuja
muutuja -= 1
appendInfoLine: muutuja
muutuja *= 2
appendInfoLine: muutuja
muutuja /= 5
appendInfoLine: muutuja

Käsk appendInfoLine on sarnane käsule writeInfoLine, ainult et kui viimane kustutab varem infoaknas olnu ära, siis appendInfoLine lisab teksti lihtsalt uuele reale.

19.3.2 Sõnaline muutuja

Sõnalise muutuja puhul on matemaatilised tehted piiratud – neid saab omavahel ainult liita. Proovi:

muutuja1$ = "te"
muutuja2$ = "re"
muutuja3 = 2
muutuja4$ = muutuja1$ + muutuja2$
writeInfoLine: "Sõnas ", muutuja4$,  " on ", 
... muutuja3, " silpi: ", muutuja1$, " ja ",
... muutuja2$, "."

Mingil määral saab neid siiski ka lahutada, st ühest stringist saab lõpust lahutada sellega kattuva stringi, aga mitte algusest:

m1$ = "tere"
m2$ = "te"
m3$ = "re"
m4$ = m1$ - m2$
m5$ = m1$ - m3$
writeInfoLine: m1$, " - ", m2$, " = ", m4$,
... " aga ", m1$, " - ", m3$, " = ", m5$

Sõnalisi muutujaid võib ka nii kombineerida, asenda 4. rida:

muutuja4$ = "'muutuja1$''muutuja2$'"

Sel viisil võib kombineerida ka uut teksti ja numbrilisi muutujaid sõnalistega, tulemus on sõnaline muutuja:

muutuja4$ = "'muutuja3'-silbiline 'muutuja1$''muutuja2$'"

Plussmärkidega arvulisi ja sõnalisi muutujaid kokku panna ei saa, siis tuleb enne arv tekstiks teisendada käsuga string$():

´´´ a = 2 tekst$ = “Väärtus on” vastus$ = tekst$ + string$(a) ´´´

Muutujate väärtust saab määrata ka mõne käsu abil. Näiteks muutuja1 väärtus on sound objekti kestus (Sound objekt peab objektiaknas olema valitud):

muutuja1 = Get total duration
writeInfoLine "Kestus on 'muutuja1' sekundit."

Muutujatega saab määrata dialoogiaknas küsitavaid väärtusi (jällegi peab Sound objekt olema valitud):

ajaaken = 0
f0alumine = 75
f0ylemine = 300
To Pitch: ajaaken, f0alumine, f0ylemine

Niisiis muutujatega saame vahetada ja kombineerida skriptis erinevaid arvulisi ja sõnalisi väärtusi. Nii saame näiteks määrata põhitooni ülemise ja alumise piiri skripti alguses ühe korra ning edasi kasutada neid väärtusi mitmete käskude parameetritena ilma. Kui siis on vaja sama analüüs teha mitme failiga uuesti natuke teiste parameetritega, saame neid väärtusi muuta ühes kohas ja säästame kõvasti aega. Ja veel enam, me saame ühe käsuga küsida mingit väärtust ja lisada selle väärtuse hiljem skriptis mingi teise käsu parameetriks.

19.4 Tsüklid

Tsüklite abil on võimalik ühte käsku mitu korda jooksutada. Selleks on vaja korratava(te)le käs(k)u(de)le vaja ümber panna for-endfor konstruktsioon. Tsükli alguses ´forkäsu järel defineeritakse muutuja, nti` ja kordade arv.

for i to 8
  appendInfoLine: "See on 'i'. kord."
endfor

Siin näites kirjutatakse infoaknasse lause 8 korda, iga kord on muutuja i väärtus ühe võrra suurem. Tegevus, mida korratakse, peab jääma ridade for ja endfor vahele.

appendInfoLine on writeInfoLine sarnane käsk, mis kuvab infoaknasse sellele järgneva teksti, ainult varasemat infoaknas olnud teksti ei kustutata. Veel infoakna juhtimise käske on appendInfo, mis ei tee lõppu reavahetust ja clearinfo, mis kustutab midagi uut trükkimata kõik infoaknast ära.

Erinevalt paljudest teistest skriptikeeltest (vähemalt R) on Praati tsüklites muutuja alati arvuline ja samm alati +1. Tsükkel ei pea algama ühest, sel juhul tuleb määrata ka algus (see võib olla ka negatiivne), aga tsüklit ei saa teha kahanevate väärtuste suunas. Näiteks tsükkel 6 kuni 9 oleks selline:

for i from 6 to 9
 appendInfoLine: "See on 'i'. kord."
endfor

Kuna skriptis võib rea alguses olla ükskõik kui palju tühikuid, on kombeks, et see, mis tsükli (ja muude süntaksielementide, mis mitut järgnevat rida hõlmavad) sisse jääb, märgitakse taandega (nt 2 tühikut). Nii on algust ja lõppu lihtsam üles leida. Ühe tsükli sees võib ka teine tsükkel olla, ja siis selle sisu võiks olla täiendava taandega. Nii on lihtsam arvet pidada, kust miski algab ja lõppeb. Aga need tühikud on ainult ilu pärast, nii et võib ka panemata jätta.

Näiteks siin on üks tsükkel teise sees:

clearinfo
for i to 3
  for j from 10 to 14
    appendInfoLine: "välimise tsükli i = ", i,
    ... " ja sisemise tsükli j = ", j
  endfor
endfor

19.4.1 Praktiline näide tsükli kasutamisest

Kuidas tsükleid Praatis praktiliselt kasutada? Näiteks on meil vaja tsüklit, kui me tahame skriptiga TextGrid failist infot välja saada: Praatis on käsud selleks, et ühest TextGridi intervallist tekst või kestused kätte saada ja me saame teha tsükli, mis käib sedasi läbi kõik intervallid.

Kõik kasutatud käsud on TextGrid objekti dünaamilises menüüs Query.

  1. Kõigepealt küsime, mitu segmenti on TextGridi 1. kihil (menüüst Query > Query interval tier > Get number of intervals).
  2. Siis teeme tsükli, mis kordab järgnevat tegevust nii mitu korda kui TextGridil on segmente
  3. Küsime esimese kihi i-nda segmendi nime (Query > Query interval tier > Get label of interval),
  4. selle intervalli algusaega (segmendi alguspunkt faili alguspunkti suhtes ajateljel, Query > Query interval tier > Get start time of interval)
  5. ja lõpuaega (Query > Query interval tier > Get start time of interval).
  6. Kestuse millisekundites saame nii, et lahutame segmendi lõpu aja alguse ajast ja korrutame tuhandega – millisekund on tuhandendik sekundit.
segmendid = Get number of intervals: 1

for i to segmendid
  nimi$ = Get label of interval: 1, i
  algus = Get start time of interval: 1, i
  ots = Get end time of interval: 1, i
  kestus = (ots - algus) * 1000
  appendInfoLine: "Segment ", nimi$, " kestus ", round(kestus), " ms."
endfor

Käsk round() ümardab arvu lähimaks täisarvuks. Kui soovid aga täpsustada komakohtade arvu, peab kasutama käsku fixed$() ja see teeb väärtuse ühtlasi sõnaliseks:

m = 0.12345
writeInfoLine: m, " lähim täisarv on ", round(m),
... ", kolme komakohaga ", fixed$(m, 3)

19.5 Kommentaarid skriptis

Oma skripte on alati mõistlik põhjalikult kommenteerida, nii enda kui teiste pärast: kui oled kirjutanud pika skripti, siis seda hiljem kasutades ei pruugi enam mäletada, mida ja miks see teeb. Samuti kui oma skripte teistega jagada, on teistel neist lihtsam aru saada, kui skript on korralikult kommenteeritud.

Kommentaarid tuleb kirjutada eraldi reale, mis algavad trellide, hüüumärgi või semikooloniga (#,! või ;), nt:

# muutuja a väärtus on ruudu külje pikkus
a = 4

Skripti tekstiga saab ka samale reale panna kommentaare, siis algab kommentaar kindlasti ainult semikooloniga:

a = 4; ruudu külje pikkus

19.6 Mis objektile skript rakendub?

Praati käsud enamasti teevad midagi mingi konkreetse objektiga, näiteks küsivad TextGridi intervallide algus- ja lõpuaegu, teevad Sound objektile põhitoonianalüüsi, küsivad Pitch objekti põhitooni väärtust mingil ajahetkel.

Skriptis olevad käsud rakenduvad sellele objektile, mis on objektiaknas valitud. Skriptiga saab leida andmeid mitmest objektist. Et vahetada valitud objekti, on skriptis käsk selectObject.

Järgmises näites rakendame vaheldumisi käske mitmele objektile:

  • Teeme failist isoleeritud_vokaalid.wav Pitch objekti.
  • Otsime failist isoleeritud_vokaalid.TextGrid märgitud intervallide keskmise põhitooni.
  • Tulemused saadame infoaknasse tabuleeritud tekstina, mille saame salvestada tabelina, kus esimeses lahtris on segmendi nimi, teises f0 väärtus.
  • Teeme tabelile ka päise, kus on tulpade pealkirjad. Selleks kasutame käsku writeInfo, et ühtlasi kustutada info-aknast kõik, mis seal enne oli. Edasi kasutame info-aknasse kirjutamiseks käsku appendInfo.
  • Kuna Pitch-objekti pärast enam vaja pole, kustutame selle skripti lõpus objektiloendist ära (käsk Remove graafiliselt asub objektiakna alumises osas).
# valime objektiloendist Sound objekti
# ja rakendame põhitoonianalüüsi käsku
selectObject: "Sound isoleeritud_vokaalid"
To Pitch: 0, 75, 600

# Selle koha peal jääb objektiloendis valituks
# loodud Pitch objekt.

# Valime TextGrid objekti ja küsime,
# mitu segmenti on 1. kihil
selectObject: "TextGrid isoleeritud_vokaalid"
segmendid = Get number of intervals: 1

# kirjutame infoaknasse tulemustetabeli päiserea
writeInfoLine: "Segment", tab$, "Põhitoon (Hz)"

# tsükkel, mis käib läbi TextGridi 1. kihi segmendid
for segment to segmendid
  # iga tsükliringi alguses valime TextGrid objekti, 
  # sest tsükli lõpus võib jääda valituks mingi muu objekt
  # (siin skriptis Pitch) ja siis saame veateate,
  # sest järgmist käsku, mis on TextGridile mõeldud
  # ei saa Pitch objektile rakendada
  selectObject: "TextGrid isoleeritud_vokaalid"

  # Küsime selle tsükliringi segmendi teksti
  # ning algus- ja lõpuaega.
  nimi$ = Get label of interval: 1, segment
  algus = Get starting point: 1, segment
  lopp = Get end point: 1, segment
  
  # valime Pitch objekti ja küsime, 
  # mis on selle segmendi keskmine põhitoon
  selectObject: "Pitch isoleeritud_vokaalid"
  pohitoon = Get mean: algus, lopp, "Hertz"
  
  # kirjutame tulemused infoaknasse
  appendInfoLine: nimi$, tab$, pohitoon

  #tsükkel lõppeb ja valituks jääb Pitch objekt
endfor

# Kui tsükkel on läbi ja kõik segmendid läbi käidud, 
# valime Pitch objekti ja eemaldame selle objektiloendist
selectObject: "Pitch isoleeritud_vokaalid"
Remove

Muutuja tab$ väärtus on tabulatsioonisümbol, seda on mugav kasutada väljade eristajana, niimoodi pärast põhitooniväärtused nt Excelisse kopeerides on andmed kahes tulbas: esimeses segmendi nimi, teises põhitooni väärtus.

Käsule appendInfoLine võib järgneda üks või mitu komadega eraldatud teksti, mis infoakna real kõik üksteise otsa laotakse.

Kui on vaja, et valitud oleks korraga mitu objekti, selleks on käsk plusObject. Näiteks saame valida Sound ja TextGrid objektid ja mõlemad korraga objektiloendist eemaldada:

selectObject: "Sound isoleeritud_vokaalid"
plusObject: "TextGrid isoleeritud_vokaalid"
Remove

19.7 Tingimused

Vahel on vaja, et sõltuvalt mõne muutuja väärtusest teeks skript erinevaid asju. Selleks on hea if-endif konstruktsioon.

Näiteks tahame, et ainult muutja ühe kindla väärtuse korral tehtaks midagi:

clearinfo
muutuja = 5
if muutuja = 5
  writeInfoLine: "Muutuja väärtus on ", muutuja
endif

Proovi seal nüüd esimesel real muutuja väärtuseks määrata mõni muu number. Kui seda jooksutada, ei juhtu mitte midagi, sest tingimus infoaknasse kirjutamiseks ei ole täidetud.

Kui tahame, et ühel juhul teeks skript üht ja kõigil teistel juhtudel teist:

muutuja = 5
if muutuja = 5
  writeInfoLine: "Muutuja väärtus on ", muutuja
else
  writeInfoLine: "Muutuja väärtus ei vasta tingimusele."
endif

Kui aga tahame, et ühel juhul üht, teisel juhul teist ja muudel juhtudel mitte midagi:

muutuja = 5
if muutuja = 5
  writeInfoLine: "Muutuja väärtus on ", muutuja
elsif muutuja = 6
  writeInfoLine: "Muutuja väärtus on nüüd ", muutuja
endif

If-konstruktsiooni lõpus peab alati olema rida endif.

Arvulise muutuja puhul saame tingimustena kasutada kõiki võrratuse märke:

  • a = b – muutuja a on võrdne b-ga
  • a < b – muutuja a on väiksem kui b
  • a > b – muutuja a on suurem kui b
  • a <= b – a on väiksem või võrdne b-ga
  • a >= b – a on suurem või võrdne b-ga
  • a <> b – a ei ole võrdne b-ga (st on suurem või väiksem)

Sõnalistele muutujatele saab rakendada ainult = (on võrdne) ja <> (kõike muud kui).

Täiendame põhitooni otsimise skripti nii, et see otsiks ainult neid segmente, millel on mingi nimi (st mille nimi oleks „kõike muud kui mitte midagi”), teistest hüppaks üle:

selectObject: "Sound isoleeritud_vokaalid"
To Pitch: 0, 75, 600

selectObject: "TextGrid isoleeritud_vokaalid"
segmendid = Get number of intervals: 1

writeInfoLine: "Segment", tab$, "Põhitoon"

for segment to segmendid
  selectObject: "TextGrid isoleeritud_vokaalid"
  nimi$ = Get label of interval: 1, segment
  # lisame siia tingimuse: if-endif vahele jäävad käsud
  # rakenduvad ainult nende segmentide korral,
  # millel on märgitud mingi tekst
  if nimi$ <> ""
    algus = Get starting point: 1, segment
    lopp = Get end point: 1, segment
    selectObject: "Pitch isoleeritud_vokaalid"
    pohitoon = Get mean: algus, lopp, "Hertz"
    appendInfoLine: nimi$, tab$, pohitoon
  endif
endfor

selectObject: "Pitch isoleeritud_vokaalid"
Remove

19.8 Kirjutame tulemused faili

Käsud writeInfo, writeInfoLine, appendInfo ja appendInfoLine kirjutavad teksti infoaknasse. Sealt tuleb see eraldi salvestada või kuhugi (nt Excelisse) kopeerida, kui ei taha, et see läheks kaotsi, kui Praati sulgeme.

Käsuga writeFile (ja writeFileLine, appendInfo, appendInfoLine) saab tulemuse kirjutada faili. Selleks on vaja asendada rida appendInfo: Minu tekst reaga appendFile: kataloog/failinimi, Minu tekst.

Nii infoakna kui faili kirjutamise käskude puhul on write ja append vahe selles, et write kirjutab varasema sisu üle (kustutab varasema) ja append lisab olemasolevale juurde. Näiteks:

writeFileLine: "C:/Documents and Settings/partel/My Documents/f0tulemused.txt",
... "Segment", tab$, "Põhitoon"

appendFile: "C:/Documents and Settings/partel/My Documents/f0tulemused.txt",
... nimi$, pohitoon, newline$

Muutuja newline$ teeb reavahetuse. Veel sarnaseid määratud muutujaid on tab$, mis trükib tabulatsiooni. Selle asemel võib muidugi tabulatsiooniklahviga sisestatavat sümbolit kasutada, aga skriptis on tab$ selgem, sest tabluatsioonimärk on “nähtamatu” nagu tühik.

Failiaadressi võib asendada ka muutujaga. Lisame kuhugi skripti algusesse rea, kus defineerime muutuja tulemusfail$:

tulemusfail$ = "C:\Documents and Settings\partel\My Documents\F0tulemused.txt"

Ja nüüd võib fileappend-real muuta failinime muutujaga:

appendFile: tulemusfail$, nimi$, tab$, pohitoon, newline$

19.9 Dialoogiakna lisamine skriptile

Et skripti universaalsemaks teha, saab lisada algusesse dialoogiakna, kus skriptis olulisi muutujaid defineerida. Siis avaneb skripti jooksutamise peale esimese asjana dialoogiaken, kus vastavaid parameetreid küsitakse ja ei pea skripti ennast muutma.

Näiteks võiks lisada eelmistes näidetes kasutatud põhitoonileidmise skriptile dialoogiakna, kus küsitakse failinime ja põhitooni piire.

Dialoogiakna algust märgib form Akna pealkiri ja lõppu endform. Nende vahel on dialoogiakna sisu. Iga rida koosneb kolmest elemendist: välja tüüp (tekst, arv, valik), muutuja nime ja vaikimisi väärtust. Näiteks kui küsime failinime (õieti objekti nime, mis on failinimi ilma laiendita), mis on sõnaline muutuja, oleks dialoogiakna vorm skriptis selline:

form Keskmine põhitoon
  sentence Failinimi Vokaalid_isol
endform

NB! Siin on muutuja nimi ilma $-märgita ja võib olla suure algustähega. Hiljem skriptis tuleb kasutada sama muutujat kujul failinimi$. Kui sõnavahedesse panna alakriips, näeb dialoogiaknas tühikut, aga muutujanimes on hiljem alakriips. Kui liikuda erinevate objektide vahel, millele enne andsime argumendiks lihtsalt tekstina objekti täisnime, siis nüüd tuleb see panna kokku failinimest ja objektitüüp jääb sinna ette endiselt litsalt tekstina: selectObject: "TextGrid " + failinimi$.

Põhitooni väärtused on positiivsed reaalarvud, nii peaks rida olema positive F0_alumine_piir_(Hz) 75.

Dialoogiaknas saab lisada muutujanimele sulgudes kommentaare, mis on dialoogiaknas nähtavad, aga hiljem muutujanimme ei jää. Siin jääb edaspidi muutujanimest *_(Hz)* ära ja muutuja on kujul f0_alumine_piir.

form Keskmine põhitoon
  sentence Failinimi Vokaalid_isol
  positive F0_alumine_piir_(Hz) 75
  positive F0_ylemine_piir_(Hz) 500
endform

# kuna nüüd on failinimi$, f0_alumine_piir ja
# f0_ylemine_piir väärtused dialoogiaknas,
# tuleks varasemal kujul read kustutada, muidu
# dialoogiaknas  määratud väärtused kirjutatakse
# üle ja dialoogiaken kaotab mõtte.

selectObject: "Sound " + failinimi$
To Pitch: 0, f0_alumine_piir, f0_ylemine_piir
selectObject: "TextGrid " + failinimi$
segmendid = Get number of intervals: 1
writeInfoLine: "Segment", tab$, "Põhitoon"
for segment to segmendid
  selectObject: "TextGrid " + failinimi$
  nimi$ = Get label of interval: 1, segment
  if nimi$ <> ""
    algus = Get starting point: 1, segment
    lopp = Get end point: 1, segment
    select Pitch 'failinimi$'
    pohitoon = Get mean: algus, lopp, "Hertz"
    appendInfoLine: nimi$, tab$, round(pohitoon)
  endif
endfor
selectObject: "Pitch " + failinimi$
Remove

Dialoogiaknas saab määrata, missuguseid väärtusi muutujatele saab anda. Arvuliste muutujate välja tüübid on:

  • real (reaalarvud),
  • positive (ainult positiivsed reaalarvud; negatiivne väärtus annab veateate),
  • integer (ainult täisarvud; komakohad ümardatakse),
  • natural (ainult positiivsed täisarvud).

Sõnalised muutujad võivad olla:

  • word (üks sõna),
  • sentence (tekst),
  • text (pikem tekst, muutuja nime ei kuvata ja väli on selle võrra suurem).

Etteantud väärtustega muutujad:

  • boolean (check box, kui on tühi, on väärtus 0, kui linnukesega, siis 1),
  • choice ja button (valik, mille nuppudel on väärtused alates 1-st).

Kui dialoogiaknas tahta mingit selgitavat teksti esitada, siis comment reale kuvatakse ainult järgnev kommentaari tekst. Väärtused, mis on skriptis, on vaikimisi väärtused.

Siin on väike näide erinevate väljatüüpidega dialoogiaknast:

form test
  comment Palun sisesta parameetrid
  real Reaalarv -0.5
  positive Positiivne_reaalarv 1.5
  integer Taisarv -10
  natural Positiivne_taisarv 2
  word Sona_(ilma_tühikuteta_string) kana
  sentence Lause Põhjatuul ja päike.
  text Tekst Ükskord vaidlesid põhjatuul ja päike selle üle...
  boolean Linnuke_(kas_on_või_pole) 0
  choice Valik 2
  button a
  button b
  button c
endform
writeInfoLine: reaalarv, tab$, positiivne_reaalarv, tab$,
# taisarv, tab$, positiivne_taisarv
appendInfoLine: sona$, newline$, lause$, newline$, tekst$
appendInfoLine: linnuke, tab$, valik

19.10 Valmis skript

Siin on nüüd kokku pandud skript, mille alguses me ütleme, millist faili (objektiaknas olevatest) kasutame, mis on põhitoonianalüüsi piirid ja kuhu faili tulemused kirjutame. Tulemuste faili kirjutame segmendi nime, kestuse (millisekundites) ja põhitooni (hertsides).

# Form peab olema skripti päris alguses, sellele võib
# eelneda kommentaare, aga ei saa olla mingeid käsuridu.
# Skripti algusesse on hea lisada paar kommentaaririda
# selle kohta, mida skript üldiselt teeb:
# See skript leiab textgridil märgendatud segmentide
# kestuse ja põhitooni. Sound ja TextGrid peavad olema
# avatud, tulemused kirjutatakse faili. Kui fail on juba
# olemas, kirjutatakse see üle ja varasem sisu läheb kaotsi.
# Skripti kirjutas Pärtel Lippus viimati muudetud 15. juuli 2024
# Skripti võib kasutada CC BY litsentsi alusel

form Keskmine põhitoon
  comment Sound ja TextGrid peavad olema objektiloendis
  sentence Failinimi Vokaalid_isol
  comment Määra põhitoonianalüüsi piirid
  positive F0_alumine_piir_(Hz) 75
  positive F0_ylemine_piir_(Hz) 500
  comment Täisaadress, kuhu tulemused salvestatakse:
  sentence Tulemusfail C:\Documents and Settings\partel\My Documents\F0tulemused.txt
endform

selectObject: "Sound " + failinimi$
To Pitch: 0, f0_alumine_piir, f0_ylemine_piir

selectObject: "TextGrid " + failinimi$
segmendid = Get number of intervals: 1

# tulemuste faili päis
writeFile: tulemusfail$, "Segment", tab$, "Kestus", tab$, "Põhitoon", newline$

# tsükkel, mis käib läbi kõik TextGridi 1, kihi segmendid
for segment to segmendid
  selectObject: "TextGrid " + failinimi$
  nimi$ = Get label of interval: 1, segment

  # kui segmendi tekst ei ole tühi
  if nimi$ <> ""
    algus = Get starting point: 1, segment
    lopp = Get end point: 1, segment
    # arvutame kestuse: lõpuaeg - algusaeg annab kestuse sekundites, korrutame tulemuse 1000-ga, et teisendada millisekunditesse
    kestus = (lopp - algus) * 1000
    selectObject: "Pitch " + failinimi$
    pohitoon = Get mean: algus, lopp, "Hertz"
    appendFile: tulemusfail$, nimi$, tab$, kestus, tab$, pohitoon, newline$
  endif
endfor

# tsükkel on läbi, eemaldame Pitch objekti
selectObject: "Pitch " + failinimi$
Remove

19.11 Muudatused Praati skriptikeele süntaksis

Praati skriptikeele süntaks tegi aastatel 2013-2014 läbi mõningase muutuse. Siin õpikus on läbivalt üritatud kasutada uuemat süntaksit, aga kuna repositooriumites leidub skripte eri aegadest, siis on hea natuke teada, kuidas vanem süntaks välja näeb, et vanu skripte vajaduse korral kasutada ja modifitseerida. Õnneks uuemates Praati versioonides töötavad nii vanad käsud kui vana skriptisüntaks endiselt ja ka ühe skripti piires võib läbisegi kasutada ka uut ja vana süntaksit.

Varasemas Praati skriptikeeles lõppesid käsud kolme punktiga sama moodi nagu menüüdes. Kolmele punktile järgnesid argumendid ilma komadeta ja sõnalised väärtused ilma jutumärkideta. Näiteks kui soovime TextGridi esimese kihi viienda segmendi tekstiks märkida sõna maja, tuleks seda teha nii:

Set interval text... 1 5 maja

Et muutuja eristuks tavalisest tekstist, tuli see tähistada ülakomadega:

segm = 5
Set interval text... 1 'segm' maja

Selle süntaksi puuduseks on see, et tekst võib ka sisaldada tühikuid ja kui on järjest mitu tühikut, siis on neid raske märgata ja kergesti tulevad sisse näpukad, mida on raske üles leida. Samuti on tülikas ja kohati ebaloogiline, et tavaline tekst on markeerimata (ilma jutumärkideta) ja muutujad tuleb jutumärkidega tähistada.

Üürikest aega 2013/2014 (alates 7. aprillist 2013 versioonist 5.3.44) oli kasutusel ka üleminekusüntaks, kus käsurida alustas do või do$ sõltuvalt sellest, kas käsu tulemiks oli arvuline või sõnaline väärtus, käsk ise ja argumendid järgnesid sellele sulgudes ja olid eristatud komadega:

segm = do("Get interval at time...", 3, 0.5)
sona$ = do$("Get label of interval...", 1, segm)

Praegune süntaks, kus käsk lõppeb koolongiga ja sellele järgnevad argumentide väärtused, mis on eristatud komadega, on Praatis kasutusel alates versioonist 5.3.63 (24. jaanuar 2014). Kõik kolm varianti Praati skriptisüntaksist töötavad siiski edasi, nii et vanu skripte uuemas Praati versioonis jooksutamiseks ümber kirjutama ei pea.

Samuti on aja jooksul toimunud muudatusi Praati käskudes. Mõningaid käske on lihtsalt korrastamise ja parema selguse eesmärgil ümber nimetatud (nt TextGrid objekti intervalli algusaja pärimise käsk oli varem Get start point... ja on praegu Get start time of interval...), teisi on asendatud sisuliste muudatuste tõttu (nt põhitoonianalüüsi käsu To Pitch... on alates versioonist 6.4 (15. november 2023) asendanud To Pitch (filtered autocorrelation)...). Et vanad skriptid oleksid endiselt kasutatavad, on ka kõik vanad käsud Praatis alles, nad on lihtsalt graafilise kasutajaliidese menüüdest peidetud. Täielikku nimekirja kõigist käskudest saab vaadata ning peidetud käske menüüdes nähtavaks teha Praat > Settings > Buttons....

Vaata lisaks

Praati manuaal, skriptid: http://www.fon.hum.uva.nl/praat/manual/Scripting.html

Mietta Lennese skriptid: https://lennes.github.io/spect/