Výpočet formantů

Pro posun na další strany použijte kurzorové šipky

Ⓒ Tomáš Bořil
borilt@gmail.com, 9. 3. 2015

Zadání

  1. Ručně otevřete soubory .TextGrid a .Wav, priklad_data.zip (milanek.wav a milanek.TextGrid).
  2. Poznamenejte si index segmentu a: ve slově mila:nek.
  3. Vytvořte skript, který
    • načte oba soubory,
    • vypočte čas poloviny segmentu a:,
    • vypočte čas začátku a konce prostřední třetiny téhož segmentu,
    • vytvoří ze zvuku objekt Formant,
    • vypíše okamžitou hodnotu F2 v půlce segmentu,
    • vypíše průměrnou F2 v prostřední třetině.

Výsledky zaokrouhlete na celá čísla.

Ruční nalezení indexu segmentu

Otevřeme soubory, oba je označíme a tlačítkem View & Edit společně zobrazíme.

V mém případě je segment s labelem a: ve 2. vrstvě a 5. intervalu.

Začátek skriptu

Nyní vytvoříme nový skript, smažeme historii, otevřeme oba soubory a historii vložíme.

Skript průběžně ukládáme do souboru s příponou .praat, abychom v případě havárie nepřišli o cenné dílo.

Read from file: "D:\AKU\milanek.TextGrid"
Read from file: "D:\AKU\milanek.wav"

Začátek skriptu

Smažeme historii, zjistíme počáteční a konečný čas našeho segmentu (operace s textgridem) a příkazy vložíme do skriptu.

Read from file: "D:\AKU\milanek.TextGrid"
Read from file: "D:\AKU\milanek.wav"
selectObject: "TextGrid milanek"
Get start point: 2, 5
Get end point: 2, 5

Všimněme si, že se vložil i příkaz na vybrání textgridu, což je v pořádku. V tomto případě se jako poslední načítal zvuk, tudíž bude i označen, bez selectObject by příkazy týkající se textgridu skončily s chybou.

Začátek skriptu

Naučme se načítané objekty pojmenovávat, abychom se na ně mohli lépe odkazovat v případě pozdějších skriptů, kde budeme pracovat s více objekty. Výhodou je, že příkazy na výběr pak nejsou závislé na konkrétním názvu souboru.

Před příkazy s načtením souboru přidáme přiřazení do proměnné, např. textID = . Příkaz na výběr objektu se pak změní na pouhý select následovaný proměnnou s odkazem.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
Get start point: 2, 5
Get end point: 2, 5

Výpočet hranic pro analýzy

Nyní vypočteme hranice.

a) Polovina segmentu

b) Začátek a konec prostřední třetiny

Proto zjištěné časy intervalu uložíme do proměnných.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5

Polovina segmentu

Polovinu segmentu vypočteme např. jako průměr t1 a t2.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2

Prostřední třetina segmentu

Nejdříve zjistíme trvání třetiny segmentu.

Tuto hodnotu pak přičteme k t1 (začátek prostřední třetiny). Pokud ji přičteme ještě jednou (a nebo naopak odečteme od koncové hranice), dostáváme konec prostřední třetiny.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina

Demonstrujme tuto "vysokou matematiku" na číselném příkladu.

Dejme tomu, že segment začíná časem 2 a končí časem 5.

Co děláme špatně?

Začali jsme prázdným skriptem, smazali historii, provedli příkazy pomocí tlačítek, vložili historii, doplnili jsme uložení výsledků výpočtů pod názvy do proměnných, začali psát své vlastní výpočty.

Ale na jednu velice důležitou věc jsme zapomněli. Na kterou?

  1. Zkontrolovat, zda neexistuje novější verze Praatu.
  2. Napsat si nejdříve celý program dopředu na papír.
  3. Normalizovat amplitudu zvuku na maximum.
  4. Průběžně ukládat skript a po větších celcích svou práci zálohovat.
  5. Vysypat koš na ploše, aby počítač nepracoval se starými soubory.

Některé jiné možnosti také třeba nejsou úplně od věci (i když některé jsou vyloženě nesmysl), ale jedna svou důležitostí ostatní výrazně převyšuje.

Čtyři z pěti studentů varují: nejoblíbenější vlastností Praatu je sekání a padání. A i kdyby nebylo, pokusí se o to Váš operační systém, a nebo rovnou celý počítač. A pokud ne on, tak si vše omylem smažete třeba sami.

Malé skripty průběžně ukládejte. Každý řádek programu, který nechcete dělat znovu, stojí za uložení (můžete použít rychlou klávesovou zkratku Ctrl+S). Před spuštěním skriptu je to naprosto nutné! To je nejrizikovější okamžik a nikdy nevíte, co se stane.

Je také nutné, abyste své dílo zálohovali. Vymyslete si takový způsob, který bude pohodlný a umožní Vám vrátit se v čase i ke starším verzím. Např. adresář zazipovat a přidávat pořadová čísla. Nevěřte ani svému počítači a pevnému disku, pravidelně si tyto soubory např. posílejte sami sobě na e-mail nebo ukládejte na externí disk. Nic není 100% spolehlivé.

Ne jednomu se už stalo, že si v rozrušení omylem klávesovou zkratkou označil celý dokument, stiskem klávesy smazal a ještě rychle uložil. Přepsání staré verze novou rozbitou je nejhorší. Smazaný soubor se dá často ještě obnovit, přepsaný soubor bohužel prakticky nikdy. S průběžnými zálohami včetně historie verzí máte vyhráno a nemusíte znovu tvořit např. týdny tvůrčí práce.

Vytvoření objektu Formant

Smažme opět historii. Formanty se týkají spektrální oblasti, proto hledejme tu správnou funkci pod tlačítkem Analyse spectrum.

Metoda To Formant (burg)... je dobrá.

Přestože nám půjde pouze o 2. formant, je dobré nechat jich extrahovat více, metoda tak většinou poskytuje kvalitnější odhady. Defaultních 5 formantů a maximální frekvence 5500 Hz by mělo dát rozumné výsledky.

Vytvoření objektu Formant

Do skriptu vložíme historii.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
selectObject: "Sound milanek"
To Formant (burg): 0, 5, 5500, 0.025, 50

Vytvoření objektu Formant

selectObject předěláme na příkaz select.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
select zvukID
To Formant (burg): 0, 5, 5500, 0.025, 50

Vytvoření objektu Formant

Pro další práci je vhodné si objekt opět pojmenovat.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
select zvukID
formantID = To Formant (burg): 0, 5, 5500, 0.025, 50

Výpočet formantů

Smažeme historii a prozkoumáme možnosti tlačítka Query objektu Formant.

Zadáním bylo

  • vypsat okamžitou hodnotu F2 v půlce segmentu,
  • vypsat průměrnou F2 v prostřední třetině.

Pro první případ využijeme funkci Get value at time, v druhém případě Get mean.

V obou okénkách zatím zadejte jakékoliv vymyšlené hodnoty, poté vložte do skriptu historii. Podle vymyšlených čísel poznáme, který parametr odpovídá kterému, a ve skriptu je nahradíme našimi proměnnými.

Vytvoření objektu Formant

Vložená historie, bude nutno nahradit vymyšlené hodnoty našimi proměnnými a výsledky také uložit.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
select zvukID
formantID = To Formant (burg): 0, 5, 5500, 0.025, 50
Get value at time: 1, 0.5, "Hertz", "Linear"
Get mean: 1, 2, 3, "Hertz"

Vytvoření objektu Formant

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
select zvukID
formantID = To Formant (burg): 0, 5, 5500, 0.025, 50
f2 = Get value at time: 2, tPolovina, "Hertz", "Linear"
f2prumer = Get mean: 2, tretina1, tretina2, "Hertz"

Vypsání hodnot

Hodnoty na závěr slavnostně vypíšeme.

textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
select zvukID
formantID = To Formant (burg): 0, 5, 5500, 0.025, 50
f2 = Get value at time: 2, tPolovina, "Hertz", "Linear"
f2prumer = Get mean: 2, tretina1, tretina2, "Hertz"
printline Okamžité F2 v polovině: 'f2:0'
printline Průměrné F2 ve druhé třetině: 'f2prumer:0'

Připomenutí: zápisem 'f2:0' v printline říkáme, že se má výpis proměnné zaokrouhlit na 0 desetinných míst (tedy vypisujeme jen celá čísla).

Úklid

Na začátek skriptu umístíme tradiční příkaz clearinfo.

Je hezké, když si skript po sobě na konci "uklidí", neboli odstraní objekty, které vytvořil.

Můžeme opět smazat historii, přepnout na hlavní okno Praat Objects, označit objekt TextGrid a dole stisknout Remove.

Po vložení historie vidíme, že k odstraňování slouží příkaz Remove. Výběr objektů přepíšeme zase na příkaz select následovaný proměnnou s ID objektu.

Úklid – finální skript

clearinfo
textID = Read from file: "D:\AKU\milanek.TextGrid"
zvukID = Read from file: "D:\AKU\milanek.wav"
select textID
t1 = Get start point: 2, 5
t2 = Get end point: 2, 5
tPolovina = (t1+t2)/2
trvaniTretina = (t2-t1)/3
tretina1 = t1 + trvaniTretina
tretina2 = t2 - trvaniTretina
select zvukID
formantID = To Formant (burg): 0, 5, 5500, 0.025, 50
f2 = Get value at time: 2, tPolovina, "Hertz", "Linear"
f2prumer = Get mean: 2, tretina1, tretina2, "Hertz"
printline Okamžité F2 v polovině: 'f2:0'
printline Průměrné F2 ve druhé třetině: 'f2prumer:0'
select textID
Remove
select zvukID
Remove
select formantID
Remove

Závěrem

Když spustíme tento skript, dočasně vytvoří objekty, ale na závěr je zase z okna Praat Objects odstraní.

Otázka na zamyšlenou – je lepší počítat okamžitou hodnotu nebo raději průměr za určitý úsek?

Jelikož se formanty pouze odhadují, mohou být dílčí okamžité hodnoty zatíženy náhodnou chybou. Průměrováním více hodnot tuto náhodnou složku potlačujeme, získáváme tak dlouhodobější trend, což je dobré pro obdržení stabilních výsledků odpovídajících lépe "pravdě".

Analýza v prostřední třetině je výhodná z toho důvodu, že tím odřízneme nejvyšší vliv tranzientů vlivem okolních hlásek.

Možná vás překvapila vysoká hodnota formantu F2. Když si pustíme tento zvuk, nejedná se o úplně klasické a:, směřuje spíše k e:, pak už hodnota okolo 1700 Hz dává smysl.

Zpět na hlavní stranu