Tyto stránky nabízejí podpůrné materiály pro kurzy Akustika řeči I a II a Řečové technologie I.
Přehled příkazů a základních programovacích technik v Praatu – Radek Skarnitzl
# Komentář |
Řádky začínající znakem # se neprovádějí, slouží k okomentování programu.
Pokud toužíme vložit komentář na řádek obsahující příkaz, použijeme znak ;
clearinfo ; Komentář |
Doporučuje se komentář vkládat:
Jako proměnná funguje jakýkoliv řetězec složený ze znaků a číslic (a některých dalších znaků, např. podtržítko). Prvním znakem musí být malé písmeno a nesmí obsahovat mezeru.
V Praatu proměnné mohou ukládat výsledné hodnoty příkazů. Př.:
trvani = Get total duration |
Některé proměnné jsou v Praatu předdefinovány, tím pádem jejich hodnotu nelze měnit:
Řetězcové (textové) proměnné
Slouží pro ukládání znakových řetězců. Od číselných proměnných se odliší znakem $ na konci názvu. Pro uložení hodnoty do řetězcové proměnné je třeba použít uvozovky. Př.:
cilove_hlasky$ = "f s š x" label$ = Get label of interval... 1 1 |
Některé proměnné jsou opět předdefinovány:
Výpis proměnných
Hodnoty uložené v proměnných většinou vypisujeme do okna Info.
Pro výpis slouží příkazy printline (přidá text do okna a skočí na další řádek), print (přidá text do okna) a echo (vyprázdní okno, vypíše text a skočí na další řádek).
Když chceme nechat vypsat hodnotu dané proměnné, zapíšeme ji v jednoduchých uvozovkách (apostrofech). Apostrofy používáme skutečně při výpisu příkazy print, při operacích s proměnnými (výpočty) se nepoužívají. U řetězcových proměnných také nesmíme zapomenout na znak $. Př.:
zacatek = Get start point... 1 1 konec = Get end point... 1 1 pulka = zacatek + (konec-zacatek)/2 printline Polovina hlasky je 'pulka'. |
Tělo for cyklu se pro přehlednost doporučuje odsadit (zejména při vnořování více for cyklů do sebe).
for počítací proměnná from počáteční hodnota to koncová hodnota tělo for cyklu: jeden či více příkazů endfor |
Počítací proměnná („i“, „k“ apod.) je ve skriptech velmi důležitá, protože definuje interval, v němž provádíme měření.
Např. pro zjištění labelu v konkrétním intervalu pomocí příkazu Get label of interval zadáváme dva argumenty: pořadí vrstvy a pořadí intervalu v ní. Při každém průchodu cyklem tak získáme tu následující značku. Př.:
pocet = Get number of intervals... 2 for i from 1 to pocet label$ = Get label of interval... 2 i printline 'label$' endfor |
if výraz tělo podmínky: žádný, jeden či více příkazů endif |
Výrazem může být test na rovnost (=), nerovnost (<>), porovnání (> nebo <, >= nebo <=). Je-li podmínka splněna, provede se tělo, není-li, skočí se za endif.
Chceme-li definovat, co se má provést, není-li podmínka splněna, použijeme rozšířenou podobu:
if výraz 1. tělo podmínky: žádný, jeden či více příkazů} … provede se, jen je-li výraz pravdivý else 2. tělo podmínky: žádný, jeden či více příkazů} … provede se, jen není-li výraz pravdivý endif |
Pokud máme více podmínek, které se navzájem vylučují, můžeme je elegantně zapsat v nejširší formě if. Skript se tak vlastně rozdělí na několik nezávislých větví. Jakmile se jednou větví vydá, už se nemůže vydat po jiné: Praat bere podmínky jednu po druhé a jakmile je nějaká splněna, vydá se do jejího těla a pak pokračuje za endif.
if výraz1 1. tělo podmínky} … provede se, jen je-li výraz1 pravdivý elsif výraz2 2. tělo podmínky} … provede se, jen není-li výraz1 pravdivý a je pravdivý výraz2 … … else poslední tělo podmínky} … provede se, jen když není pravdivý ani jeden z předchozích výrazů endif |
Mezi objekty se musíme přepínat, jako kdybychom na ně klikali myší a volili položky z jejich nabídek Query.
Existuje několik možností zvolení objektu. Nejjednodušší (ale nejméně univerzální) je napsat jeho jméno. Př.:
select Sound nahravka1 select Intensity veta3 |
Elegantnější je každý právě zvolený objekt „zakódovat“, uložit ho do proměnné. Je konvencí používat v názvu „ID“. Takto většinou na začátku skriptu zakódujeme objekty Sound a TextGrid a později jakékoli další vytvořené objekty. Př.:
textID = selected("TextGrid") |
Podobným způsobem můžeme i zjistit jméno daného objektu; použijeme jen textovou proměnnou a znak $ za příkazem selected. Př.:
jmeno$ = selected$("Sound") |
Pokud ve skriptu operujeme s více objekty, bývá třeba na začátku každého cyklu (for cyklu, podmínky) zvolit objekt, který je k dalšímu příkazu potřeba. Př.:
zvukID = selected ("Sound") textID = selected ("TextGrid") select zvukID To Intensity... 100 0 yes intID = selected ("Intensity") select textID no = Get number of intervals... 2 for i from 1 to no select textID label$ = Get label of interval... 2 i if label$ = "a" a = Get start point... 2 i b = Get end point... 2 i select intID int = Get mean... a b energy printline 'label$''tab$''int:2' endif endfor |
Kdybychom na začátku for cyklu nezvolili textID, cyklus by jednou proběhl, „překlikli“ bychom na intID a podruhé by se skript zastavil s hláškou Command „Get label of interval…“ not available for current selection.
Zmíníme ještě jeden způsob volby objektů, a to podle jejich pořadí. Př.:
zvuk_staryID = selected("Sound",1) ; zvolí první objekt typu Sound v objektovém okně zvuk_novyID = selected("Sound",2) ; zvolí druhý objekt typu Sound |
Na začátku skriptu definujeme cílové hlásky jako textovou proměnnou, jejíž členy budou odděleny mezerami. Př.:
frikativy$ = "f v s z š ž x h" ; pozn. [x] je symbol po české ch |
Po zjištění aktuální hlásky pak vložíme podmínku s použitím funkce index. Zároveň musíme přidat podmínku, která vyloučí prázdné intervaly (protože prázdný řetězec je „nalezen“ vždy). Celá podmínka bude vypadat takto:
if (index (frikativy$, label$)) and (label$ <> "") |
Pozor! Funkce index skutečně jen zjišťuje, zda se druhý řetězec nachází v prvním řetězci. Výše uvedený způsob zápisu může být proto velmi nebezpečný v tom, že skript bude ve skutečnosti dělat něco jiného, než jsme zamýšleli. Pokud např. definujeme následujícím způsobem seznam dlouhých vokálů, budeme možná nepříjemně překvapeni, že budou nacházeny i krátké vokály. Ale skutečně je tomu tak, protože samotné znaky i e a o u jsou také součástí tohoto řetězce. A pokud bude label intervalu obsahovat znak mezera, i takový interval bude vyhodnocen jako vyhovující.
vokaly$ = "i: e: a: o: u:" |
Použití funkce index proto vyžaduje vysokou obezřetnost a v současné době ho již vyučující předmětu Akustika řeči nedoporučuje, protože může napáchat více škody než užitku. Naprosto bezpečné řešení, přitom ne o moc pracnější (použijeme-li schránku pro kopírování opakujících se částí) je vyjmenovat požadované labely jako samostatné jasně ohraničené řetězce ve vícenásobné podmínce:
if label$ = "i:" or label$ = "e:" or label$ = "a:" or label$ = "o:" or label$ = "u:" |
Následující skript měří formanty v prostřední třetině krátkých vokálů (monoftongů):
zvukID = selected ("Sound") textID = selected ("TextGrid") select zvukID To Formant (burg)... 0 3 3000 0.025 50 formantID = selected ("Formant") vokaly$ = "i i: e e: a a: o o: u u:" select textID no = Get number of intervals... 1 for i from 1 to no select textID label$ = Get label of interval... 1 i if label$ = "i" or label$ = "e" or label$ = "a" or label$ = "o" or label$ = "u" a = Get start point... 1 i b = Get end point... 1 i c = a + (b-a)/3 d = b - (b-a)/3 select formantID f1 = Get mean... 1 c d Hertz f2 = Get mean... 2 c d Hertz printline 'label$''tab$''f1:1''tab$''f2:1' endif endfor |
Předpokládejme, že pracujeme současně se zvuky a TextGridy:
1. zjistíme počet souborů daného typu
pocet = numberOfSelected("Sound") |
2. pomocí for cyklu objekty zakódujeme
for i from 1 to pocet soundID'i' = selected("Sound",i) ; tím zakódujeme první objekt typu Sound jako soundID1, druhý jako soundID2 atd. textID'i' = selected("TextGrid",i) ; první TextGrid bude uložen pod proměnnou textID1, druhý jako textID2 atd. endfor |
3. postupné překódování v dalším for cyklu
for i from 1 to pocet soundID = soundID'i' select soundID … … endfor |
Jedná se o nutnou přesmyčku. Bez ní bychom se setkali s příkazy jako printline ‚jmeno$’i“, které ovšem v Praatu neexistují.
Následující skript tedy všem TextGridům přidá vrstvu se jménem morfemy. Kromě samotného příkazu Insert interval tier můžeme strukturu pole kopírovat a měnit pouze typy objektů.
pocet = numberOfSelected("TextGrid") for i from 1 to pocet textID'i' = selected("TextGrid",i) endfor for i from 1 to pocet textID = textID'i' select textID Insert interval tier... 1 morfemy endfor |
Jakýkoli skript tedy můžeme poměrně snadno předělat tak, aby fungoval s více objekty (načtenými soubory). Jen je třeba dávat pozor na počítací proměnnou: v rámci jednoho for cyklu nemůžeme dvakrát použít proměnnou se stejným názvem. Buď ve vnitřním nebo vnějším for cyklu musíme použít například jméno k.
Následující skript je příkladem, který všechny body využívá:
zvukID = selected ("Sound") textID = selected ("TextGrid") ; 1. kódování select zvukID To Harmonicity (cc)... 0.01 75 0.1 1 harmID = selected ("Formant") ; 2. další objekty select textID no = Get number of intervals... 1 ; 3. počet intervalů for i from 1 to no ; 4. for cyklus select textID label$ = Get label of interval... 1 i ; 5. zjištění hlásky if label$ = "m" or label$ = "n" or label$ = "ň" ; 6. porovnání hlásky a = Get start point... 1 i b = Get end point... 1 i ; 7. zjištění hranic select harmID hnr = Get mean... a b ; 8. zjištění hodnot printline 'label$''tab$''harm:2' endif endfor ; 9. výpis hodnot a ukončení cyklů select harmID ; 10. úklid Remove select zvukID plus textID |
Poznámky: ne vždy se načtou všechny stránky interaktivní prezentace. Titulní stránka i poslední strana jsou výrazně odlišné od ostatních. Pokud máte tedy podezření,
že poslední stránka není skutečně tou poslední, použijte tlačítko Refresh v prohlížeči pro znovunačtení celé prezentace. Vyžaduje prohlížeč kompatibilní s HTML5, vyzkoušeno v Chrome.
Zajímavé klávesové zkratky: o nebo g pro rychlý průchod mezi stránkami, f pro zobrazení přes celou obrazovku.
Fourier Series 3D interaktivní demonstrace principu Fourierových řad
Tyto stránky a demonstrace byly vytvořeny za podpory vnitřního grantu FF UK v Praze, rok 2015: FF_15_TO1_076 Tvorba multimediálních stránek pro předměty Akustika řeči a Řečové technologie.