Az alábbi jegyzet elsősorban a Digitális bölcsészet mesterképzés (MA) Számítógépes nyelvészet szakirányának gyakorlati kurzusain történő felhasználás céljából készült, de hasznos segédanyagként szolgálhat bármely, a számítógépes beszédfeldolgozás területén tevékenykedő, a Praat2 program használatával most vagy eddig csak felületesen ismerkedő kutató számára is. A jegyzetnek nem célja átfogó képet adni a számítógépes beszédfeldolgozás általános módszereiről és alapfogalmairól, hanem előfeltételezve azok legszükségesebb részének ismeretét, gyakorlati és alkalmazás-specifikus irányban igyekszik útmutatóul szolgálni. A Praat program funkcióinak rövid tárgyalásán és felhasználói felület bemutatásán kívül sor kerül az alkalmazás rendkívül kreatívan kihasználható programozási lehetőségeinek taglalására is.
A jegyzet HTML verziójában3 a tartalomjegyzék, a kereszthivatkozások és a jegyzetszámok a könnyebb navigációt szolgálandó hiperhivatkozásként funkcionálnak.
A Praat program egy teljesen ingyenesen és szabadon letölthető4, nyílt forráskódú, folyamatos fejlesztés és CC BY-SA licenc (Creative Commons Attribution ShareAlike5) alatt álló alkalmazás, amely az alábbi platformok mindegyikén elérhető:
Telepítést nem igényel (Windows, Macintosh, Linux), a hivatalos weboldalról letöltött csomagból kitömörített bináris állomány bárhonnan futtatható, a merevlemezen pedig mindössze néhány MB memóriát foglal el. A forráskód letöltése és fordítása, csak bizonyos rendszerek (FreeBSD, SGI, Solaris, HPUX) illetve abban az esetben szükséges, ha a felhasználó további módosításokkal és lehetőségekkel is élni kíván (pl. az alapértelmezett nyelv mellet Python szkripteket is szeretne használni a beépített programozási felületen5).
A program indítása és vezérlése többféle módon lehetséges:
Az első esetben a kitömörített bináris állomány futtatásával (Windows: Praat.exe, MacOS X: Praat.app, Linux: praat) a 3. fejezetben ismertetésre kerülő Praat Objects és Praat Picture ablak grafikus felületén tudjuk megkezdeni a munkát. Unix és MacOS X rendszerek alatt parancssorból is indíthatunk Praat szkripteket a parancs argumentumában megadott paraméterekkel (Windows rendszer alatt ez csak a Praatcon7 segédprogrammal valósítható meg). A harmadik alternatívaként említett külső vezérlésre a Senpraat8 nevezetű (a hivatalos weboldalról szintén letölthető) segédprogram szolgál, amellyel a Praat egy már elindított példányának tudunk parancssorból (vagy akár egy másik alkalmazásból) üzeneteket elküldeni és azokkal vezérelni a program működését. Az üzeneteket a következő szintaxis szerint kell továbbítanunk:
sendpraat [időlimit] praat|als üzenet
Ahol az üzenet rész tartalmazza az elküldendő utasítást vagy utasításokat. A vezérléshez használható parancsok előre definiáltak. Az alábbi "Quit" parancsszót tartalmazó üzenet például leállítja a Praat programot:
./sendpraat 0 praat Quit
A következő példa már valamivel komplikáltabb, mivel több, egymás után végrehajtandó utasítást is tartalmaz, melyek közül az első egy argumentummal (a beolvasandó hangfájl elérési útjával) is el van látva:
./sendpraat 1000 praat "Read from file: hangok/hello.wav" "Play reverse" "Remove"
Az üzenet hatására a Praat program először a hangok könyvtárból beolvassa a hello.wav fájt, majd visszafelé lejátssza azt, végül eltávolítja a listából. A példából az is látható, hogy a szóközökkel és argumentumokkal ellátott utasításokat idézőjelek között kell megadni, hogy az szóköz utáni rész ne új utasításként értelmeződjön.A parancssori utasítások szerkesztésével és használatával a Praat szkriptekről szóló 5. fejezet foglalkozik majd részletesebben, mivel főként a feldolgozási folyamatok automatizálásánál illetve komplikáltabb feladatok megvalósításához lesznek hasznosak. A programmal funkcióival való elsődleges ismerkedést egyszerűbb és átláthatóbb a grafikus interfész használatával elkezdeni.
A grafikus kezelőfelület a program (Windows: Praat.exe, MacOS X: Praat.app, Linux: praat) indítása után két külön egységre, a Praat Objects és a Praat Picture ablakra tagolódik. A Praat Objects ablak a Praatban használt különféle objektumok (pl. a feldolgozandó hangfájlok) általános kezelésére, a Praat Picture pedig az objektumok vizuális megjelenítésére szolgál.
Az 1. ábrán látható Praat Objects ablak funkcióit tekintve négy különböző részre tagolható tovább:
A statikus menü (az ablak fölső részén, horizontális elrendezésben) és a kezelőgombok (az objektumokat tartalmazó lista alatt) a program használata során folyamatosan és változatlan lehetőségekkel elérhetők (megjegyzés: MacOS X rendszereknél a statikus menü Praat menüje a fölső tálcán található meg). Az objektumok listája az objektumok kezelése (beolvasás, létrehozás, eltávolítás) során értelemszerűen megváltozhat, a dinamikus menü (az ablak jobb oldalán, vertikális elrendezésben) pedig mindig az aktuálisan kijelölt objektum(ok) típusának megfelelően ajánl fel további kezelési lehetőségeket (az 1. ábrán kijelölt objektum esetében ez a Sound Help, View & Edit, Play stb. utasítások lesznek). A statikus menü Save menüje a dinamikus menü utasításaihoz hasonlóan szintén az aktuálisan kijelölt objektum típusának megfelelő formátumokat kínál fel a merevlemezre történő kiíráshoz.
A listában szereplő minden objektum három alapvető tulajdonsággal rendelkezik:
Az 1. ábra listájában található objektumok esetében ezek a tulajdonságok az 1. táblázatban látható értékeket veszik fel:
Azonosító | Típus | Név |
---|---|---|
1 | Sound | hang1 |
2 | Sound | hang2 |
3 | Sound | hang3 |
4 | Pitch | hang3 |
5 | Intensity | hang3 |
A lista alatt található kezelőgombokkal a lista elemein különféle műveleteket hajthatunk végre. Az aktuálisan kijelölt objektumokat például a Remove gombbal tudjuk eltávolítani, míg a Copy gombbal egy másolatot készíthetünk róla (ha másolat nevét nem változtatjuk meg, akkor az így keletkező és az eredeti objektum csak azonosító számukban fognak különbözni).
A statikus menü legfontosabb funkciói:A listában beolvasott vagy létrehozott objektumok a számítógép fizikai memóriájába töltődve közvetlenül hozzáférhetők, ezért a számítógép memóriakapacitásának függvénye, hogy egyszerre mennyi és milyen méretű objektumot tudunk a listába helyezni. A fájlok beolvasására általános esetben az Open menü "Read from file..." utasítása szolgál. Használatakor a beolvasott fájl formátumát a Praat automatikusan azonosítja (amennyiben a formátum támogatott), és a listába bekerülő objektumot hozzárendeli egy a fájl formátumának megfelelő típushoz. Az 1. ábrán látható lista első három objektuma például a "Sound" típushoz kerültek hozzárendelésre. Az Open menüben található egyéb alternatívákkal a beolvasandó fájl formátumát és a belőle létrehozandó objektum típusát tudjuk előre specifikálni. Az "Open long sound file..." utasítás például nem "Sound", hanem "LongSound" típusú objektumokat fog létrehozni a beolvasott hangfájlokból.
Új objektumokat a New menüben tudunk létrehozni párbeszédpanelek segítségével. A párbeszédpanelek az objektum típusának és a létrehozás módjának megfelelően paraméterezhetők.
A 2. ábrán látható párbeszédpanel a New menü "Create Sound from formula..." utasítása után ugrik elő. Az utasítás végén szereplő "..." karakterek jelzik, hogy az utasítás további paramétereket ("Name", "Number of channels", "Start time", "End time" stb.) vár, amelyeket a párbeszédpanel vonatkozó mezőiben tudunk megadni, majd az "OK" gombra kattintva jóváhagyni.
A dinamikus menü bizonyos utasításának használatakor szintén új, az eredet objektumból leképezett objektumok kerülnek a listába. A "Sound" típusú objektumok esetében új objektumot eredményez például az "Analyse periodicity" utasításcsoport "To Pitch..." utasítása, amely a kijelölt hangfelvételből kimért F0 adatokat egy, az eredetivel azonos nevű, "Pitch" típusú objektumba helyezi (az 1. ábrán objektumlistájában így jött létre a "To Pitch..." leképező utasítást a 3. objektumra alkalmazva a 4. objektum). Többek között ezeknek a leképezési műveleteknek köszönhető, hogy a Praat programban, bizonyos objektumok bizonyos tulajdonságait (például egy hangfelvétel dallamát) az eredeti objektumtól függetlenül, önálló objektumként tudjuk további vizsgálatok alá vonni.
A Praat Picture ablak részben a Praat Objects ablak dinamikus menüjében található ("Draw..") utasításokkal (nem minden objektumnál elérhető), részben pedig saját menürendszere által vezérelhető. A 3. ábrán látható hullámforma például az 1. ábra objektumlistájában található "Instensity" típusú (a beszéd intenzitásával kapcsolatos adatokat tartalmazó) 5. objektum vizuális megjelenítése. Kirajzolásához a 5. objektum kijelölése után a dinamikus menü "Draw..." utasítását kellett alkalmazni, amelyet a 4. ábrán látható párbeszédpanelen tudunk paraméterekkel ellátni.
A Praat Picture ablak saját menürendszerében további (globálisan a statikus menü részét képező) lehetőségek érhetők el, melyekkel a rajzolási felület különféle tulajdonságait tudjuk beállítani:
A szerkesztő ablakok a Praat Objects ablak dinamikus menüjéből hívhatók elő a "View & Edit" utasítás használatával, amennyiben a kijelölt objektum típusa ezt elérhetővé teszi. Az előhívott szerkesztő ablakok felületének bizonyos funkciói és menürendszere az objektumok típusának függvényében különböznek egymástól. Az 5. ábrán egy "Sound" típusú objektum szerkesztő ablaka látható:
Az ablak alján található gombok és a csúszka a szerkesztő ablakban történő navigációhoz (léptetés és zoomolás), a fölöttük lévő három szürke sáv pedig a lejátszáshoz (alsó sáv: egész fájl lejátszása, középső sáv: aktuális ablak lejátszása, felső sáv: kijelölt szakasz lejátszása) szolgálnak. Ugyanezek a funkciók érhetők el a View menüből vagy a megfelelő gyorsbillentyűk használatával is.
A File menüben lehetőségünk van az objektum valamely kijelölt részének:
A Select menüben állíthatjuk be a kijelöléseket és a kurzor helyzetét (ez egérrel is végezhető művelet), melyek aktuális állapotát a Query menüben tudjuk lekérdezni (pl. "Get selection length"). Az 5. ábrán látható többi menü kifejezetten objektum-specifikus utasításokat tartalmaz. A "Sound" típusú objektumok esetén a hangfájlok hullámformáján kívül az alábbi tulajdonságokat van lehetőségünk a szerkesztő ablakban megjeleníteni:
Az azonos elnevezésű menükből lehetőségünk van a fölsorolt jellemzők:
Mivel a Praat meglehetősen sokféle típusú objektumot használ, a jegyzetnek nem célja a hozzájuk tartozó, típusonként egyéni sajátosságokat mutató szerkesztő ablakok kimerítő ismertetése. A program funkciót tárgyaló 4. fejezetben néhányuk még szóba kerül.
A Praat info ablak felelős a Praat Objects és a szerkesztő ablakokból elérhető lekérdező utasítások eredményeinek megjelenítéséért, továbbá a Praat szkriptek is ezt az ablakot használják mint standard kimenet. Csak lekérdező vagy közvetlen kiíratást végző utasítások futásakor jelenik meg. Önálló menürendszere is van, amellyel a kimenet tartalmát szöveges állományba írathatjuk ki, illetve használhatjuk a szokásos szerkesztési (Undo, Redo, Copy, Paste stb) és keresési (Find, Replace) műveleteket is.
A program egyik legismertebb és legfontosabb funkciója a beszédakusztikai elemzés. A Praatban használható objektumok nagy része is ezt a célt támogatja. A hangfájlok beolvasása, generálása vagy felvételek készítése (New: "Record mono/stereo sound...") után számtalan feldolgozási lehetőség elérhető a Praat Objects ablak dinamikus menüjéből, melyek segítségével a beszéd szupraszegmentális jegyeinek átfogó, a beszédkutatás területén széles körben használt algoritmusokkal történő vizsgálatát tudjuk megkezdeni. A 6. ábra a beszéd akusztikai jellemzőinek a Praat programban elérhető objektumtípusait és leképezési lehetőségeit jeleníti meg (korántsem a teljesség igényével).
Mint az előző fejezetben már említésre került, az objektumokat a Praat Objects ablak dinamikus menüjéből tudjuk leképezni egymásból a megfelelő utasítások használatával ("To Pitch...", "To Intensity...", "To PitchTier..." stb.). A létrejött objektumok egy részét szerkesztő ablakokban is vizsgálni tudjuk. A 7. ábrán egy "PitchTier" típusú (adott időpillanatokban mért F0 adatokat tartalmazó) objektum szerkesztő ablaka látható.
Lekérdezéseket közvetlenül a Praat Objects ablak dinamikus menüjéből is végezhetünk az objektumok tulajdonságira és a bennük tárolt adatokra vonatkozóan. A lekérdező utasítások Praat szkriptekbe ágyazásával a további (statisztikai jellegű) elemzésekhez jól használható adattáblák is generálhatóak. A hangfájlokból képzett beszédakusztikai objektumokat a Save menüből egy a típusoknak megfelelő formátumban tudjuk a lemezre kiíratni. A "PitchTier" objektumokat például elmenthetjük az alábbi szöveges formátumban:
File type = "ooTextFile"
Object class = "PitchTier"
xmin = 0
xmax = 20.835714285714285
points: size = 605
points [1]:
number = 0.29285714285714237
value = 79.71932258134986
points [2]:
number = 0.3028571428571424
value = 78.9987075127485
points [3]:
Vizsgálatainkhoz sok hasznos beépített eljárást is használni tudunk. Például "Sound" vagy "Intensity" típusú objektumok esetén a "To TextGrid (silences)..." utasítással létrejön egy "TextGrid" típusú objektum, amelyben a beszédben található szünetek határai automatikusan jelölésre kerülnek.
A program egy rendkívül hasznos, sokféle célra felhasználható funkciója az annotáció. A hangfájlokhoz készített annotációs ("TextGrid" típusú) objektumokban a beszéd folyamát különféle címkékkel láthatjuk el, tetszőleges szempontból szegmentálva és feliratozva annak megfigyelt vagy automatikusan detektált tulajdonságait és eseményeit. Az annotációra legkézenfekvőbb példa, mikor a beszédet a felvételen elhangzottak alapján szöveges átirattal látjuk el (mintegy feliratozzuk), de az előző alfejezet végén említett, szünetdetektálásra szolgáló eljárás eredménye is annotálásnak minősül, hiszen a beszédfolyam "sounding" és "silence" címkékkel történő szegmentálását kapjuk eredményül.
Annotációs objektumokat a "To TextGrid..." (dinamikus menü) vagy a "Create TextGrid..." (New menü) utasításokkal hozhatunk létre. A szegmentálást és a címkézést végezhetjük az erre szolgáló szerkesztő ablakokban, melyek az annotált objektum és annotáció (a "TextGrid" típusú objektum) együttes kijelölése után érhetők el a dinamikus menü "View & Edit" utasításával.
A 8. ábrán két annotációs szint ("silences", "transcription") is látható egymás alatt, amelyet tetszőleges számú (korlátokat a memória illetve az átláthatóság szabhat) annotációs szintekkel bővíthetünk tovább, ha egyéb elemzési szempontokkal is szeretnénk vizsgálatunkba vonni. A vastag, kék színű vertikális vonalak jelzik a szegmentumok határait (létrehozásuk a Boundary menü parancsaival vagy gyorsbillentyűkkel lehetséges), amelyek közé szövegeket (címkéket) illeszthetünk.
Az annotációk kezelése a Praat Objects ablak dinamikus menüjében található utasításokkal illetve Praat szkriptek használatával is lehetséges. A Query utasításcsoporttal például információkat kérdezhetünk le a szegmentumok időbeli helyzetével és címkéivel kapcsolatban ("Get start time...", "Get label of interval..." stb.), amelyeket egyéb akusztikai elemzésekkel is összehangolhatunk.
A Praat programban lehetőség van tanuló algoritmusok létrehozására is, ami kétféle paradigma keretében valósítható meg:
Az első mintaillesztésen alapuló osztályzáshoz, a második pedig fonológiai transzformációkhoz használható. A módszerek működéséről és felhasználási céljairól a Praat hivatalos honlapjának föntebb hivatkozott oldalin érhető el bővebb információ.
Az ábrák készítésével kapcsolatos tudnivalókat a Praat Picture ablakkal foglalkozó 3.2 fejezet taglalta röviden. A rajzoló felületen lehetőség van a létrehozott ábrák különféle formátumokban (PDF, PNG, EPS) történő exportálására és további feldolgozására is. A felhasználható speciális szimbólumok listája és kódolási módja a program hivatalos oldalán12 tekinthető meg.
Beszéd szintetizáláshoz többféle módszert alkalmazhatunk:
Az első esetben a Praatban elérhető beszédakusztikai objektumok ("Pitch", "Formant", "Intensity") generálása és a bennük tárolt fizikai paraméterek manipulálása útján hozhatunk létre beszédhangokat. Az alábbi utasítások sorozata például a [baa] hangsort tartalmazó "Sound" objektumot generálja le:
pitchTier = Create PitchTier: "source", 0, 0.5
Add point: 0.0, 150
Add point: 0.5, 100
pulses = To PointProcess
Remove points between: 0, 0.02
Remove points between: 0.24, 0.31
Remove points between: 0.48, 0.5
source = To Sound (phonation): 44100, 0.6, 0.05, 0.7, 0.03, 3.0, 4.0
removeObject: pitchTier, pulses
selectObject: source
Create FormantGrid: "filter", 0, 0.5, 10, 550, 1100, 60, 50
Remove formant points between: 1, 0, 0.5
Add formant point: 1, 0.00, 100
Add formant point: 1, 0.05, 700
Remove formant points between: 2, 0, 0.5
Add formant point: 2, 0.00, 500
Add formant point: 2, 0.05, 1100
plusObject: "Sound source"
Filter
A KlattGrid beszédszintetizálóról, amely szintén a beszéd akusztikai tulajdonságaira támaszkodik, David Weenink tanulmányában13 olvashatunk bővebben. A Praat programban a "Create KlattGrid..." utasításon keresztül elérhető funkció.
Az artikulációs szintézis esetén különféle artikulációs paraméterek beállításával nyílik lehetőség beszédhangok szintetizálására, amelyhez a "Speaker" és az "Artword" objektum használható fel. A "Speaker" objektum létrehozásakor például megadhatjuk a beszélő nemét (férfi, nő, gyermek), az "Artwort" objektum segítségével pedig a beszédszervek működését tudjuk egy szerkesztő ablakban numerikus paraméterekkel szabályozni (9. ábra).
A New menü "Sound" utasításcsoportjában érhető el a "SpeechSynthesizer" nevű funkció ("Create SpeechSynthesizer..."), amely begépelt szövegből gépi beszédet szintetizál. Használata során meg kell adnunk a beviteli szöveg nyelvét és kódolási formáját.
A Praat program percepciós kísérletek lebonyolításához is kiválóan felhasználható mint prezentációs eszköz: alkalmas stimulusok (kép, hang, szöveg) bejátszására, a válaszok rögzítésére és az eredmények feldolgozására. A funkció egyik negatív sajátossága a rejtettség, ugyanis kísérletek létrehozására a grafikus felületen nincsen lehetőségünk. A prezentációkat egy konfigurációs állomány (a szerzők szóhasználatában: "experimental file") segítségével tudjuk vezérelni, amelyben különféle paraméterek állíthatók be: megjelenő szövegek, bejátszandó stimulusok, választási lehetőségek stb. A kísérletek konfigurálásával kapcsolatban a Praat hivatalos weboldalán14 bővebb útmutatás és példák is elérhetők.
A kísérlet megkezdéséhez a konfigurációs állományt a Praat programba előbb be kell olvasni, majd az így létrejött "ExperimentMFC" objektumot a "Run" utasítással lefuttatni. Az eredményül kapott adatokat (a stimulusra adott válasz és reakcióidő) az "Extract results" utasítással lehet a kísérlet végén kinyerni.
A beszéd akusztikai elemzése és szintetizálása mellett a Praat programban természetesen lehetőségünk van a hangfelvételek akusztikai tulajdonságainak manipulációjára is, amelyhez különféle filterek (a dinamikus menü "Filter" utasításcsoportjában, illetve a "KlattGrid" objektumon keresztül elérhetők), valamint a "Manipulation" objektum 10. ábrán látható szerkesztő felülete használható fel. Az beszéd intenzitását a közvetetten generálható "IntensityTier" objektum segítségével tudjuk még modulálni.
Érdemes megemlíteni a dinamikus menü "Convert" utasításcsoportjában szereplő "Lenghten (verlap-add)..." és a "Change gender..." utasításokat is. Előbbi a beszéd tempójának és időtartamának megváltoztatására, utóbbi a beszélő nemének megváltoztatására szolgál.
A Praat alapvetően nem statisztikai programcsomagnak készült, de az alábbi módszerek használatát támogatja:
Az utóbbi kettőt a "TableOfReal" típusú objektumokban tárolt adatokból kiindulva lehetséges megkezdeni, míg a többdimenziós skálázás esetében a "Dissimilarity" objektumtípus használandó.
Az előző fejezetben tárgyalt funkciókat, a program eszköztárát képező beépített szkript nyelv megismerésével tudjuk a leghatékonyabban kiaknázni (teljes dokumentációja15 elérhető a Praat hivatalos weboldalán). A Praat szkriptek használatának hatóköre a program teljes felületére és az említett funkciók egészére kiterjed, illetőleg bizonyos funkciók másképpen nem is érhetők el.
A Praat szkript tulajdonképpen egy speciális célú, de teljesen általános sajátosságokkal bíró, jellegét tekintve imperatív (parancs-alapú) és procedurális (eljárás-orientált) programozási nyelvnek tekintendő. Futtatási környezetét a Praat program biztosítja, és egy erre szolgáló felületen (vagy a 2. fejezetben említett parancssoros módon) vezéreli a szkriptek működését. Mivel egy szkript nyelvről van szó, az elkészített programkódok fordítása nem szükséges. A Praat sorról sorra értelmezi és végrehajtja a kódban található utasításokat.
A szkriptek futtatásának három lehetséges útja van:
Az futtatás első esetében a Praat menü "New Praat script" vagy "Open Praat script" utasítását kell használnunk. A felbukkanó ablakban szerkeszthetjük meg vagy olvashatjuk be korábban elkészített szkriptjeinket, amelyeket a "Run" utasítással (Run menü) tudunk lefuttatni.
A 11. ábrán látható szkript kódja két utasítást tartalmaz, amelyek egy-egy szöveget íratnak ki a Praat Info ablakba (a "writeInfoLine" egyúttal törli is az ablak tartalmát), amely a grafikus felületen standard kimenetként szolgál, esetünkben az alábbi szövegeket fogja tartalmazni:
Hello world!
This is my first Praat script.
A futtatás második esetben a grafikus interfész használatát megkerülve egy, a futtatni kívánt szkript elérési útját tartalmazó argumentummal indítjuk parancssorból a Praat (Windows felhasználók esetében a Praatcon) programot:
/Applications/Praat.app/Contents/MacOS/Praat /Users/user/hello.praat
Amennyiben a "hello.praat" Praat fájl a 11. ábrán látható kódot tartalmazza, a kimenet az előző esettel azonos lesz, annyi különbséggel, hogy a szöveg nem a Praat Info ablakban, hanem a parancssorban jelenik meg.
A Sendpraat programmal is futtathatunk szkripteket a parancssoros megoldással egyező módon (a szkript elérési útja, mint argumentum). A kimenet ekkor a Praat felületén (például a Praat Info ablakban) lesz észlelhető.
Mint azt a fejezet elején jeleztük, a Praat program minden funkciója vezérelhető szkriptek segítségével. A grafikus felület ablakinak menürendszerében található összes utasítás elérhető a programkódban elhelyezett, azonos nevű parancsok használatával, amelyeket a Praat program 5.4-es verziójában a ":" karakter után lehet argumentumokkal ellátni (régebbi verziókhoz íródott szkriptek továbbra is kompatibilisek):
Utasítás neve: argumentum1, argumentum2, argumentumn
Az Open menü "Read from file..." utasítását például az alábbi módon tudjuk előhívni:Read from file: "/a fájl/elérési/útja/hello.wav"
A beolvasott objektum eltávolítása a listából:
Remove
A szkriptek készítésénél mindig figyelmet kell fordítani arra, hogy csakis az aktuálisan kijelölt objektum típusának megfelelő utasításokat próbáljunk a dinamikus menüből előhívni, ellenkező esetben a Praat a "Command not available for current selection" hibaüzenettel tér vissza. Ha a szkriptben olyan ("..." karakterekkel végződő) utasítást alkalmazunk, amelyet a grafikus felületen párbeszédpanelek segítségével kellene ellátnunk különféle paraméterekkel, akkor ugyanezeket a paramétereket (a párbeszédpanel mezőibe írt adatokat) a szkript kérdéses utasításában is el kell helyeznünk mint egymástól vesszővel elválasztott argumentumokat. A 2. ábrán használt "Create Sound from formula..." utasítás párbeszédpaneljét például az alábbi módon tudjuk paraméterezni:
Create Sound from formula: "sineWithNoise", 1, 0, 1, 44100, "1/2 * sin(2*pi*377*x) + randomGauss(0,0.1)")
Az utasítások szerkesztéséhez hasznos segédletként szolgál a "Paste History" parancs (a szkriptek futtatásához használt ablak Edit menüjéből elérhető), amely a program grafikus felületén kiadott utasítások parancssori változatát tartalmazó naplófájl megtekintésére szolgál (lásd 12. ábra).
A nyelv egy rendkívül jól kihasználható sajátossága, hogy az Praatban használt utasítások eredményét változókban is tudjuk tárolni. Az alábbi szkript például a kiválasztott objektum nevét a "name$", a dinamikus menüből meghívott "Get total duration" utasítás (az objektumok teljes időtartamát kérdezi le) eredményét pedig a "duration" elnevezésű változóba menti el:
name$ = selected$ ("Sound")
duration = Get total duration
Az értékadás után a name$ változó az objektum nevét, a duration változó pedig az objektum teljes időtartamát fogja tárolni másodpercben. A változókra a szkript későbbi parancsaiban is hivatkozhatunk, például a writeInfoLine parancs argumentumaiban, amely a Praat Info ablakban a változók értékét fogja megjeleníteni:
writeInfoLine: "A ", name$, " nevű hangfájl teljes hossza: ", duration
Ha az előhívott utasítás eredménye nem egy kiíratható érték, hanem egy új objektum, akkor a változó az objektum azonosítóját fogja tartalmazni:
soundID = Create Sound from formula: "sineWithNoise", 1, 0, 1, 44100, "1/2 * sin(2*pi*377*x) + randomGauss(0,0.1)"
A fönti utasítás hatására egyrészt a listába kerül egy új objektum a "Create Sound from formula..." utasításban megadott paraméterekkel, másrészt létrejön a soundID nevű változó, ami a létrejött "Sound sineWithNoise" objektum azonosítóját fogja tárolni értékeként. Erre az értékre az objektum későbbi kiválasztásánál hivatkozhatunk majd (lásd következő alfejezet).
Az objektumok listájának kezelése nem csak a grafikus felületen, de szkriptekben kiadott utasításokkal is lehetséges. Az objektumok kijelöléséhez, kijelölésből való eltávolításához vagy hozzáadásához, a kijelölésben lévő objektumok és tulajdonságainak lekérdezéséhez a Praat szkriptek speciális parancsokat és az objektumok 3.1. fejezetben taglalt tulajdonságait használják fel.
A kijelölés kezelésére az alábbi parancsok szolgálnak:
Az objektumokra azok különböző tulajdonságaival (azonosító, típus, név) tudunk hivatkozni a parancsok argumentumában:
selectObject: 2
A fönti példa az objektum azonosítóját használja hivatkozásként (ami az 1. ábrán látható lista esetén a "Sound hang2" objektumra mutat). Az objektumok nevére csak azok típusával együtt hivatkozhatunk (idézőjelek között), mivel a név és a típus az azonosítóval ellentétben nem feltétlenül egyedi tulajdonságok (a listában tulajdonképpen együtt képezik az objektum "teljes nevét"). Az alább következő példában használt utasítás a "hang3" nevű objektumok közül a "Pitch" típussal rendelkezőt fogja kijelölni. Ha több "Pitch" típusú objektum van a listában "hang3" névvel (a teljes név sem egyedi tulajdonság), akkor a legutóbb (legnagyobb azonosító számmal) létrejött kerül kijelölésre:selectObject: "Pitch hang3"
Van lehetőségünk egyszerre több objektum kijelölésére is újabb argumentumok bevonásával. Az alábbi példában látható parancs egyszerre három objektum kijelölését végzi azonosítók alapján:
selectObject: 1, 2, 3
Az összes objektumot az alábbi utasítás jelöli ki:
select all
Természetesen módunkban áll olyan változókra is hivatkozni, amelyek az előző alfejezetben bemutatott módon hoztunk létre, és egy objektum egyedi azonosítóját tartalmazzák:
selectObject: soundID
Az objektumok tulajdonságait változók és speciális kifejezések segítségével tudjuk lekérdezni. Az aktuálisan kiválasztott objektum tejes nevét (típus és név) az alábbi parancs a fullName$ nevű változóba tárolja el:
fullName$ = selected$ ()
Ha csak az objektum nevét kívánjuk lekérdezni, mivel tudjuk, hogy a kérdéses objektum típusa "Sound":
name$ = selected$ ("Sound")
Több kijelölt objektum esetén a harmadik objektum nevét:
name$ = selected$ ("Sound", 3)
Az későbbi egyértelmű azonosítás érdekében a név helyett lekérdezhetjük az objektum azonosítóját is:
soundID = selected ("Sound", 3)
A kijelölt objektumok számának lekérdezése:
n = numberOfSelected ()
Az algoritmusok szerkesztéséhez és értelmezéséhez fontos tudnivaló, hogy új objektumok létrehozása vagy beolvasása után az aktuális kijelölés mindig az új objektumot tartalmazza.
A Praat szkriptekben fellelhető minden olyan nyelvi elem, ami egy procedurális nyelv programozásaz idei évi eszköztárában szokásos módon fellelhető. Az előző alfejezetekben már szó esett a változókról, amelyek esetében habár többféle típusról is beszélhetünk (numerikus, sztringek különféle fajtái, tömb), a Praat meglehetősen szabadon kezeli őket és csak bizonyos esetekben, a "formok" használata által (lásd következő fejezet) kötődnek előzetes deklarációhoz. A korábbi példák közül a karakteres információt tartalmazó változók (ilyen volt a "name$" és a "fullName$") nevét mindig "$" jellel kell lezárnunk, aminek betartásával túl is jutottunk a típus-meghatározásokra vonatkozó legrigorózusabb megkötésen.
A változókra való hivatkozás karakteres környezeten belül egyszeres aposztrófok között történik:
name$ = "Pistike"
writeInfoLine: "A beszélő neve: 'name$'"
Ha a fönti példa második sorában nem aposztrófok között hivatkoznánk a "name$" változóra, akkor a változó értéke ("Pistike") helyett a változó neve ("name$") jelenne meg a Praat Info ablakban. Az újabb verziók (5.3, 5.4) szintaxisa szerint a változókat önálló argumentumként szerepeltetjük:
name$ = "Pistike"
age = 14
writeInfoLine: name$, " életkora: ", age, " év"
A változók értékén az értékadás közben különféle műveleteket végezhetünk, amihez a szokásos operátorokon (+, -, * stb.) kívül speciális függvények is felhasználhatók. Néhány példa:
# A karakterlácok összefűzése, az eredmény hosszának lekérdezése
string$ = "Hello" + " " + "world"
length = length (string$)
# A karakterlánc részletének kiíratása
hello$ = left$ (string$, 5)
writeInfoLine: "Első 5 karakter: ", hello$
# Numerikus érték egészre kerekítése
f0_mean = Get mean: 0, 0, "Hertz"
f0_mean = round(f0_mean)
A folyamatokat automatizáló komplex algoritmusokban természetesen lehetőségünk van egyéb nyelvi eszközök: ciklusok, feltételes utasítások, és eljárások használatára is. A következő kommentekkel ellátott példában két for ciklus segítségével a listában minden kijelölt "Sound" típusú objektumon ugyanazt a műveletet, az alapfrekvencia értékek leképezését végezzük el:
n = numberOfselected ("Sound")
# Első for ciklus: az objektumok azonosítójának lekérdezése a sound tömb típusú változóba (a tömb elemi: sound[1], sound[2]... sound[n])
for i from 1 to n
sound[i] = selected ("Sound", i)
endfor
# Második for ciklus: objektumok kiválasztása (sound[1]...sound[n]) és a
"To Pitch" utasítás alkalmazása minden kiválasztott objektumra
for i from 1 to n
selectObject: sound[i]
To Pitch: 0, 75, 600
endfor
Ha a fönti kódot az 1. ábra listájában látható objektumokra alkalmazzuk, akkor a program futása során létrejön a "Sound" típusú objektumokból képzett "Pitch hang1", "Pitch hang2" és "Pitch hang3" objektum, amelyek a "To Pitch..." utasításban elhelyezett paramétereknek (0, 75, 600) megfelelő alapfrekvencia értékeket tartalmazzák.
Az előző példát egy feltételes utasítással is kibővítve készíthetünk egy olyan szkriptet, amely az átlagos alapfrekvencia alapján valószínűsíti a hangfájlokon rögzített beszélők nemét (férfi beszélő < 150 Hz < női beszélő):
n = numberOfSelected ("Sound")
for i from 1 to n
sound[i] = selected ("Sound",i)
endfor
for i from 1 to n
selectObject: sound[i]
name$ = selected$ ("Sound")
To Pitch: 0, 75, 600
f0mean = Get mean: 0, 0, "Hertz"
if f0mean > 150
appendInfoLine: "A ",name$," fájl beszélője valószínűleg nő"
else
appendInfoLine: "A ",name$," fájl beszélője valószínűleg férfi"
endif
endfor
A szkript futása során, az előző példával egyezően létrejönnek a megfelelő "Pitch" típusú objektumok, majd amennyiben a kimért alapfrekvencia adatatok átlaga 150 Hz alatti, a "A [fájl neve] fájl beszélője valószínűleg férfi", ellenkező esetben a "A [fájl neve] fájl beszélője valószínűleg nő" üzenet jelenik meg a Praat Info ablakban.
A Praat szkriptek paraméterezett vezérlését jelentősen megkönnyíti az úgynevezett formok használata, amelyek különféle, az indítás előtt bevihető argumentumokkal látják el őket futtatás előtt. Az argumentumok bevitelét a felhasználó egy párbeszédpanel segítségével tudja megoldani. Az alábbi, a szkript elején elhelyezendő kód egy ilyen form leírását adja meg, amely futtatás után a 11. ábrán látható párbeszédpanelt jeleníti meg.
form Detect Gender
word output_name results.txt
choice input 1
button selected_objects
button directory
positive threshold 150
boolean write_pitch_data yes
endform
A fönti form használatával az előző fejezet végén bemutatott szkript bővített változatának működését tudjuk majd szabályozni (például a nem meghatározásához szolgáló küszöbértéket átállítani). Az argumentumok beállításával tulajdonképpen változók deklarációját és értékadását végezzük el. A "Detect Gender" form második sora egy "output_name$" nevű (a formokon belül a "$" jel elhagyható), "word" típusú (szóköz nélküli karakterlánc) karakteres változót deklarál, melynek alapértelmezett értéke a "result.txt": az eredmények tárolására szolgáló fájl elérési útja. A "threshold" nevű argumentum egy positive (valamilyen 0-nál nagyobb valós szám) típusú numerikus értéket vár, a write_pitch_data pedig egy logikai változó, amely az algoritmusban egy ki/bekapcsolható opció használatát fogja szabályozni. Az input változó a beviteli metódusnak kiválasztott opció (alkalmazás a kijelölt objektumokra vagy egy beolvasott könyvtár teljes tartalmára) sorszámát tárolja (alapértelmezett értéke: 1).
A formhoz tartozó szkript teljes forráskódja:
form Detect Gender
word output_file output/results.txt
choice input 1
button selected_objects
button directory
positive threshold 150
boolean write_pitch_data yes
endform
system_nocheck mkdir output
deleteFile: output_file$
appendFileLine: output_file$, "Fájl", tab$, "Átlagos alapfekvencia", tab$, "Beszélő neme"
if input = 1
n = numberOfSelected ("Sound")
if n = 0
exitScript: "Nincs hangfájl kiválasztva"
endif
for i to n
sound[i] = selected ("Sound", i)
endfor
for i from 1 to n
selectObject: sound[i]
name$ = selected$ ("Sound")
@analyze ()
endfor
endif
if input = 2
input_directory$ = chooseDirectory$ ("Adja meg a hangfájlokat tartalmazó könyvtár elérési útját!")
Create Strings as file list: "wavList", input_directory$ + "/*.wav"
select Strings wavList
number_of_inputfiles = Get number of strings
if number_of_inputfiles = 0
Remove
exitScript: "A könyvtárban nem található Wav fájl"
endif
for i from 1 to number_of_inputfiles
selectObject: "Strings wavList"
file$ = Get string: i
Read from file: input_directory$ + "/" + file$
name$ = selected$ ("Sound")
@analyze ()
endfor
endif
Read Table from tab-separated file: output_file$
View & Edit
procedure analyze ()
To Pitch: 0, 75, 600
if write_pitch_data
Write to text file: "output/" + name$ + ".Pitch"
endif
f0mean = Get mean: 0, 0, "Hertz"
if f0mean > threshold
appendFileLine: output_file$, name$, tab$, f0mean, tab$, "nő"
else
appendFileLine: output_file$, name$, tab$, f0mean, tab$, "férfi"
endif
endproc
A szkript a kiválasztott input opciónak megfelelően két szálon (alkalmazás a kijelölt objektumokra vagy egy könyvtár tartalmára) haladhat tovább, de mind a két esetben az "analyze" nevű eljárást fogja meghívni és végrehajtani a kijelölésben/könyvtárban lévő összes hangfájlon. Az eredményeket ezúttal nem a Praat Info ablakban, hanem az output_file$ nevű változóban megadott fájlba íratja ki (a writeFileLine parancsokkal) az adatokat tabulátor jelekkel tagolva egymástól. A összes elemzés elvégzése után az eredményeket tartalmazó fájlt "Table" típusú objektumként beolvassa ("Read Table from tab-separated file...") és egy szerkesztő ablakban meg is jeleníti.
A szkripteket elmentésük után más szkriptekből és parancssorból is meghívhatjuk (parancssorban a grafikus funkciók nem elérhetők, meghívásuk a program leállását okozza). Ilyenkor a formokba beépített argumentumok értékét is meg kell adnunk szóköz karakterrel elválasztva egymástól:
runScript: "detect_gender.praat", "output/results.txt", 1, 150, "yes"
A szkript működésének kontrolálására, paraméterek bevitelére nem csak indításkor van lehetőség, hanem tulajdonképpen a kódban bárhol elhelyezhetünk megszakításokat újabb adatok bevitele vagy választási lehetőségek felkínálása céljából. Erre szolgál a pause utasítás, amely ideiglenesen felfüggeszti a program futását. A beginPause és az endPause kifejezések között pedig további információkat kérhetünk be a felhasználótól:
beginPause: "..."
comment: "Ez a program már két éve fut..."
comment: "Kérjük értékelje, hogy mennyire unja már!"
choice: "Válasz:", 1
option: "Kissé"
option: "Meglehetősen"
option: "Nagyon"
endPause: "Folytatás", 1
A szkriptek futásának teljes megszakítására szolgál az exit parancs, amelyet bizonyos programfuttatási feltételek (például szerepel-e listában feldolgozható objektum) negatív eredménnyel végződő tesztelése után vethetünk be. Hibaüzetek kiíratására (a megszakítás indoklására) is alkalmas.
A gyakrabban használt és általános céllal készített szkriptjeinket sokszor érdemes a Praat program grafikus kezelőfelületén is elhelyezni. Erre a szkriptek futtatására szolgáló szerkesztő ablak menürendszerében van lehetőségünk az "Add to fixed menu..." vagy az "Add to dynamic menu..." utasítások használatával. Az előbbi esetében a szkript statikus menürendszerben elfoglalt helyét kell meghatároznunk, az utóbbi esetben pedig, hogy milyen típusú objektumok kijelölésekor legyen elérhető a dinamikus menüben.