Praat is a program for "doing phonetics by computer" created by Paul Boersma. Find out more about it on it's home page.
Various tips, tricks, scripts and thoughts on Praat. Hide contents
nocheck select all
nocheck Remove
length = 2
half = length/2
Articulatory synthesis tutorial
Create Speaker... speaker Male 2
Create Artword... hallo length
Set target... 0 0.5 Interarytenoid
Set target... length 0.5 Interarytenoid
Set target... 0 1 LevatorPalatini
Set target... length 1 LevatorPalatini
Set target... 0 0.1 Lungs
Set target... 0.03 0 Lungs
#Set target... half 0.7 Masseter
#Set target... half 0.2 OrbicularisOris
Set target... 0.0 -1 Hyoglossus
Set target... length 1 Hyoglossus
Set target... 0.0 -0.4 Masseter
Set target... length -0.4 Masseter
#Set target... 0.0 0.4 Hyoglossus
#Set target... length 0.4 Hyoglossus
#Set target... 0.0 -0.4 Masseter
#Set target... length -0.4 Masseter
select Speaker speaker
plus Artword hallo
To Sound... 22050 25 0 0 0 0 0 0 0 0 0
Play
Beatroot by Simon Dixon is a system for beat tracking. Here's a small script for integrating this analysis with Praat.
s1=selected("Sound")
Write to WAV file... /tmp/forbeatroot.wav
system java -jar /home/johanf/dev/beatroot/beatroot-0.5.3.jar /tmp/forbeatroot.wav -o /tmp/forbeatroot.txt
tg1=To TextGrid... beats
m1=Read Matrix from raw text file... /tmp/forbeatroot.txt
nr = Get number of rows
for i to nr
b'i' = Get value in cell... i 1
endfor
select 'tg1'
for i to nr
Insert boundary... 1 b'i'
endfor
select 'm1'
Remove
select 's1'
plus 'tg1'
Edit
Load all wav files in a dir and concatenate recoverably. Save Sound and TextGrid to collection.
form Concatenate all wavs
word dir /home/johanf/
endform
wavPattern$ = dir$+"*.wav"
Create Strings as file list... fileList 'wavPattern$'
ns = Get number of strings
for i to ns
dum$ = Get string... i
str'i'$ = dum$
endfor
for i to ns
wavFileName$ = dir$+str'i'$
s'i' = Read from file... 'wavFileName$'
#name$ = selected$("Sound")
#name2$ = replace$(name$,"_"," ",5)
endfor
select s1
for i from 2 to ns
plus s'i'
endfor
Concatenate recoverably
outFileName$ = dir$+"all.Collection"
Write to binary file... 'outFileName$'
s1=selected("Sound")
s1$=selected$("Sound")
p1=noprogress To Pitch... 0.01 60 750
q75=Get quantile... 0 0 0.75 Hertz
q25=Get quantile... 0 0 0.25 Hertz
ceiling=1.5*q75
floor=0.75*q25
select 's1'
Edit
editor Sound 's1$'
Pitch settings... floor ceiling Hertz autocorrelation automatic
vfloor=(floor div 50)*50
vceiling=((ceiling div 50)+1)*50
Advanced pitch settings... vfloor vceiling no 15 0.03 0.45 0.01 0.35 0.14
printline floor: 'floor:0' ceiling: 'ceiling:0'
printline vfloor: 'vfloor:0' vceiling: 'vceiling:0'
This draws a spectrum with LPC smoothing and formants based on the selection in a TextGridEditor.
form Draw spectrum and formants
positive Number_of_formants: 4
choice Maximum_formant_(Hz): 1
button Custom
button 5000
button 5500
positive Custom_value_(Hz) 5000
endform
if maximum_formant = 1
maxf = custom_value
endif
if maximum_formant = 2
maxf = 5000
endif
if maximum_formant = 3
maxf = 5500
endif
printline 'maxf'
resf=maxf*2
cur = Get cursor
endeditor
s1=selected("Sound")
tg1=selected("TextGrid")
select 's1'
Extract part... cur-0.0125 cur+0.0125 Gaussian1 1 no
s2=selected("Sound")
Resample... 'resf' 50
s3=selected("Sound")
To Formant (burg)... 0 'number_of_formants' 'maxf' 0.025 50
f1=selected("Formant")
Down to FormantTier
ft1=selected("FormantTier")
Down to TableOfReal... yes no
tor1=selected("TableOfReal")
nc = Get number of columns
for i from 2 to nc
fn=i-1
fv'fn' = Get value... 1 i
dum = fv'fn'
printline F'fn': 'dum:0'
endfor
select 's3'
#Pre-emphasize (in-line)... 50
To Spectrum... yes
spec1=selected("Spectrum")
To Ltas (1-to-1)
ltas1=selected("Ltas")
max = Get maximum... 0 0 None
min = Get minimum... 0 0 None
ce=ceiling(max/20)*20
fl=floor(min/20)*20
select 'spec1'
#Erase all
Plain line
Line width... 1
Draw... 0 'maxf' 'fl' 'ce' yes
Marks bottom every... 1 1000 yes yes no
pause
LPC smoothing... 'number_of_formants' 50
spec2=selected("Spectrum")
Line width... 2
fl=fl+20
ce=ce+20
Draw... 0 'maxf' 'fl' 'ce' no
Axes... 0 'maxf' 0 1
Line width... 1
Dotted line
for i from 2 to nc
fn=i-1
dum = fv'fn'
tdum=dum+150
tt$ = "F"+"'fn'"
Draw line... 'dum' 0 'dum' 1
Text... 'tdum' Centre 0.96 Half 'tt$'
endfor
plus 'spec1'
plus 'ltas1'
plus 'tor1'
plus 'ft1'
plus 'f1'
plus 's3'
plus 's2'
Remove
select 's1'
plus 'tg1'
<screenshot ?>
/* Not finished */
Some code here.
This draws a Bark scaled F1/F2-plot based on an annotated waveform. Other scales are possible as well.
# Draw f1f2-plots of vowels current editor
#clearinfo
# 1: Bark
# 2: Mel
# 3: Semitones
# 4: Erb
procedure WarpHz type inHz
warp=inHz
if type = 1
warp=hertzToBark(inHz)
elsif type = 2
warp=hertzToMel(inHz)
elsif type = 3
warp=hertzToSemitones(inHz)
elsif type = 4
warp=hertzToErb(inHz)
endif
endproc
Move cursor to... 0
first_interval = 0
highest_end = 0
vow=0
warpType=1
intoVowel=0.5
repeat
lab$=Get label of interval
st=Get starting point of interval
en=Get end point of interval
if en > highest_end
highest_end = en
endif
if st = 0
first_interval=first_interval+1
endif
Select next interval
if first_interval < 2 && lab$ != ""
#printline 'st' 'en' 'lab$' 'first_interval'
vow=vow+1
time'vow'=st+((en-st)*intoVowel)
lab'vow'$=lab$
endif
until first_interval > 1
#clearinfo
Time step settings... fixed 0.01 100
Show analyses... yes no no yes no highest_end
for i from 1 to vow
dumtime = time'i'
dumlab$ = lab'i'$
#printline 'dumtime' 'dumlab$'
Move cursor to... dumtime
f1'i' = Get first formant
f2'i' = Get second formant
#f3'i' = Get third formant
#printline 'dumtime' 'dumlab$' 'f1' 'f2'
#fm1 = hertzToBark(f1'i')
#fm2 = hertzToBark(f2'i')
#fm3 = hertzToBark(f3'i')
#printline fm1_'i' = 'fm1'
#printline fm2_'i' = 'fm2'
#printline fm3_'i' = 'fm3'
endfor
endeditor
#fappendinfo /home/johanf/formant_values.psc
#Erase all
#clearinfo
from_x=3000
to_x=500
step_x=-500
from_y=1000
to_y=200
step_y=-200
call WarpHz warpType from_x
from_x_Warp=warp
call WarpHz warpType to_x
to_x_Warp=warp
call WarpHz warpType from_y
from_y_Warp=warp
call WarpHz warpType to_y
to_y_Warp=warp
Axes... from_x_Warp to_x_Warp from_y_Warp to_y_Warp
Draw inner box
One mark left... to_y_Warp no yes no 'to_y'
One mark left... from_y_Warp no yes no 'from_y'
One mark top... to_x_Warp no yes no 'to_x'
One mark top... from_x_Warp no yes no 'from_x'
x=from_x+step_x
while x > to_x
call WarpHz warpType x
x_Warp=warp
One mark top... x_Warp no no yes
x=x+step_x
endwhile
y=from_y+step_y
while y > to_y
call WarpHz warpType y
y_Warp=warp
One mark left... y_Warp no no yes
y=y+step_y
endwhile
clearinfo
#t1=Create TableOfReal... name vow 2
for i from 1 to vow
dumlab$ = lab'i'$
dumf1=f1'i'
dumf2=f2'i'
#Set value... i 1 dumf1
#Set value... i 2 dumf2
printline 'dumlab$' 'dumf1:0', 'dumf2:0'
#printline ipasign'i'$="'dumlab$'"
call WarpHz warpType dumf1
f1=warp
call WarpHz warpType dumf2
f2=warp
Text... 'f2' Centre 'f1' Half 'dumlab$'
endfor
#fappendinfo /home/johanf/ipasigns.psc
When converting a praat eps file to png (e.g. for web publishing) with gs, the whole Picture window display is included in the png file, rendering lots of extra white space. One solution is to crop the image using the Netpbm package.
Example:
gs -sDEVICE=ppmraw -dTextAlphaBits=4 -r120 -sOutputFile=- -sNOPAUSE -q praat.eps -c showpage -c quit | pnmcrop | pnmmargin -white 10 | pnmtopng > praat.png
Or just use the EPSCrop option:
gs -sDEVICE=png16m -dTextAlphaBits=4 -dEPSCrop -r120 -dSAFER -dBATCH -dNOPAUSE -sOutputFile=$soundDir/$pngFile2 -q $soundDir/$epsFile
See a demo here: mbrola.php
(just a sketch)
clearinfo
s1 = selected("Sound")
for i from 1 to 21
lb = barkToHertz(i-1)
hb = barkToHertz(i+1)
cf'i' = (lb+hb)/2
bw'i' = hb - lb
endfor
gender$ = "m"
#maxform = 5500
minpitch = 125
if gender$ == "m"
#maxform = 5000
minpitch = 60
endif
for j from 1 to 21
select 's1'
ccf = cf'j'
cbw = bw'j'
Filter (gammatone)... 'ccf' 'cbw'
s2 = selected("Sound")
noprogress To Harmonicity (cc)... 0.01 'minpitch' 0.1 1
h1 = selected("Harmonicity")
meanh = Get mean... 0 0
if meanh != undefined
hm'j'=meanh
else
hm'j'=0
endif
plus 's2'
Remove
endfor
for j from 1 to 21
ccf = cf'j'
chm = hm'j'
printline -- 'ccf:0' 'chm'
endfor
This analyses a Sound and gives a Pitch object with the curve of the intensity (instead of the frequency) of the fundamental component, which is obtained from a Spectrogram of the Sound.
form Intensity of fundamental component
real Time_step_(s): 0.0 (= auto)
positive Pitch_floor_(Hz): 75.0
positive Pitch_ceiling_(Hz): 600.0
boolean Info_window 0
endform
ns=numberOfSelected("Sound")
if ns != 1
exit Please select exactly one Sound object!
endif
s1=selected("Sound")
select 's1'
if time_step = 0
tstep=0.75/pitch_floor
else
tstep=time_step
endif
winsize=3/pitch_floor
hw=winsize/2
ct=tstep/2
dur = Get total duration
noprogress To Pitch... 'time_step' 'pitch_floor' 'pitch_ceiling'
p1=selected("Pitch")
nfr=Get number of frames
for i from 1 to nfr
fct'i' = Get time from frame number... 'i'
pi'i'= Get value in frame... 'i' Hertz
endfor
select 's1'
noprogress To Spectrogram... 'winsize' 5000 'tstep' 20 Gaussian
spec1=selected("Spectrogram")
for i from 1 to nfr
cct=fct'i'
cp=pi'i'
pint'i' = 0
if cp != undefined
pow=Get power at... 'cct' 'cp'
pint'i' = 10 * log10(pow*20000)
endif
cpint=pint'i'
#printline 'cct' 'cp' 'pow' 'cpint'
endfor
select 'p1'
To Matrix
m1=selected("Matrix")
for i from 1 to nfr
val=pint'i'
Set value... 1 'i' val
endfor
To Pitch
p2=selected("Pitch")
mean=Get mean... 0 0 Hertz
max=Get maximum... 0 0 Hertz Parabolic
stdev=Get standard deviation... 0 0 Hertz
if info_window
clearinfo
printline Time_step Window_size Mean Stdev Max
printline 'tstep' 'winsize' 'mean' 'stdev' 'max'
endif
select 'm1'
Remove
select 'p2'
Test of websvn display:
This labels a selection in a TextGridEditor with an IPA vowel character. The label is based on comparing the sound in the selection by shortest formant distance to a number of example vowels. The vowels are taken from the wikipedia entries on vowels.
include formant_values.psc
include ipasigns.psc
dir$="/media/polo/JohanFrid/wp_vokaler/"
wavPattern$ = dir$+"*.wav"
ssel=selected("Sound")
stg=selected("TextGrid")
s1s=Extract sound selection (preserve times)
endeditor
s1=Resample... 16000 50
st = Get starting time
en = Get finishing time
testdur = Get total duration
# male voice
noprogress To Formant (burg)... 0 5 5000 0.025 50
for1=selected("Formant")
fm1=Get mean... 1 0 0 Bark
fm2=Get mean... 2 0 0 Bark
fm3=Get mean... 3 0 0 Bark
if 0
# female voice
noprogress To Formant (burg)... 0 5 5500 0.025 50
for1=selected("Formant")
fm1=Get mean... 1 0 0 Bark
fm2=Get mean... 2 0 0 Bark
fm3=Get mean... 3 0 0 Bark
fm1=fm1-1
fm2=fm2-1
fm3=fm3-1
endif
bestdist=1000000000
clearinfo
for i from 1 to 28
#a$="0"+"'i'"
#a$=right$(a$,2)
dist = abs(fm1-fm1_'i')+abs(fm2-fm2_'i')+abs(fm3-fm3_'i')
#dist = abs(fm1-fm1_'i')+abs(fm2-fm2_'i')
ipa$=ipasign'i'$
dum1=fm1_'i'
dum2=fm2_'i'
dum3=fm3_'i'
printline 'ipa$' 'fm1:1'-'dum1:1' 'fm2:1'-'dum2:1' 'fm3:1'-'dum3:1'
if dist < bestdist
bestdist = dist
bestsound = i
endif
endfor
str1=Create Strings as file list... fileList 'wavPattern$'
printline --------
ipa$=ipasign'bestsound'$
printline 'bestsound' 'ipa$' 'bestdist'
s2=Create Sound... sineWithNoise 0 0.2 16000 0
select 'str1'
dum$ = Get string... bestsound
thesound$=dir$+dum$
s3s=Read from file... 'thesound$'
s3=Resample... 16000 50
select 's1'
plus 's2'
plus 's3'
s4=Concatenate
Play
select 's1s'
plus 's1'
plus 'for1'
plus 's2'
plus 's3s'
plus 's3'
plus 's4'
plus 'str1'
Remove
select stg
ipatier=0
nt = Get number of tiers
for i from 1 to nt
tn$ = Get tier name... 'i'
if tn$ = "IPAlabel"
ipatier=i
endif
endfor
if ipatier=0
Insert interval tier... 1 IPAlabel
ipatier=1
endif
nocheck Insert boundary... 1 st
nocheck Insert boundary... 1 en
mid = (en+st)/2
cin=Get interval at time... 1 mid
ipa$=ipasign'bestsound'$
Set interval text... 1 cin 'ipa$'
plus ssel
# praat
#
# This is a script that lets you label a bunch of wav files
# in an existing subdir 'wav'.
Text writing preferences... UTF-8
homePrefix$=""
# Create Strings as file list... works relative to where the script is,
# not where the script is run from so we need one copy in each fp's dir.
# The script does not create the subdirs 'TextGrid' and 'intervals'
# These must be created first!
str1=Create Strings as file list... fileList1 wav/*.wav
Sort
nStr=Get number of strings
for i from 1 to nStr
select 'str1'
wavFileTail$=Get string... i
tgFileTail$=wavFileTail$-".wav"+".TextGrid"
ivFileTail$=wavFileTail$-".wav"+".intervals"
wavFile$="wav/"+wavFileTail$
tgFile$="TextGrid/"+tgFileTail$
ivFile$="intervals/"+ivFileTail$
# set up for labeling
# (add a silence/sounding tier as this facilitates keyboard navigation)
s1=Read from file... 'wavFile$'
if fileReadable(tgFile$)
tg1=Read from file... 'tgFile$'
else
tg2=To TextGrid (silences)... 100 0 -25 0.2 0.1 silent sounding
select 's1'
tg3=To TextGrid... vowels
plus 'tg2'
tg1=Merge
select 'tg2'
plus 'tg3'
Remove
select 'tg1'
endif
plus 's1'
Edit
if fileReadable("movepause.sh")
system ./movepause.sh&
endif
pause
# write the TextGrid file
# (extract the second tier as we don't need the silence/sounding tier)
select 'tg1'
nt=Get number of tiers
if nt > 1
iv1=Extract tier... 2
tg4=Into TextGrid
endif
Write to text file... 'tgFile$'
# also write an interval file with one lab start end per row
# (might be easier to read for some programs)
# need to delete it since we append
filedelete 'ivFile$'
tierNo=1
nInt=Get number of intervals... tierNo
for iv from 1 to nInt
lab$=Get label of interval... tierNo iv
if lab$ != ""
stp=Get start point... tierNo iv
enp=Get end point... tierNo iv
fileappend "'ivFile$'" 'lab$' 'stp' 'enp''newline$'
endif
endfor
plus 's1'
if nt > 1
plus 'tg1'
plus 'iv1'
plus 'tg4'
endif
Remove
endfor

How to warp (stretch and compress) the durations of the segments of one version of an utterance to mimic those of another version of the same utterance.
s1 = selected("Sound",1)
s2 = selected("Sound",2)
s1$ = selected$("Sound",1)
s2$ = selected$("Sound",2)
select 's2'
Copy...
Rename... 's1$'_into_'s2$'
s2n = selected("Sound")
Formula... 0
sr = Get sampling frequency
winlen = 0.032
hwinlen = winlen/2
dx = 0.01532
select 's1'
plus 's2'
To MFCC... 12 'winlen' 'dx' 100 100 0
mfcc1 = selected("MFCC",1)
mfcc2 = selected("MFCC",2)
minus 'mfcc1'
x1 = Get time from frame number... 1
dur = Get total duration
ct = x1
plus 'mfcc1'
To DTW... 1 0 0 0 0.056 yes yes 2/3 < slope < 3/2
dtw1 = selected("DTW")
frn=0
while ct < dur
frn=frn+1
pt = Get time along path... 'ct' Highest
pt'frn' = pt+randomGauss(0,0.00001)
ct=ct+dx
endwhile
ct = x1
for i from 1 to frn
select 's1'
pt=pt'i'
sw=pt-hwinlen
ew=pt+hwinlen
Extract part... 'sw' 'ew' Gaussian1 1 no
s3=selected("Sound")
Rename... 's3'
swt=ct-hwinlen
ewt=ct+hwinlen
ct=ct+dx
stsamp = round(swt*sr)
ensamp = round(ewt*sr)
select 's2n'
Formula... if col > stsamp && col <= ensamp then self+Sound_'s3'_[col-stsamp] else self fi
select 's3'
Remove
endfor
How to warp (stretch and compress) the durations of the segments of one version of an utterance to mimic those of another version of the same utterance.
minp=50
maxp=200
winlen = 0.025
tstep = 0.01
s1 = selected("Sound",1)
#tg1 = selected("TextGrid",1)
s2 = selected("Sound",2)
select 's1'
To PointProcess (periodic, cc)... 'minp' 'maxp'
To TextGrid (vuv)... 0.02 0.01
tg1 = selected("TextGrid",1)
select 's1'
Copy...
s1n = selected("Sound")
dur1 = Get total duration
plus 's2'
To MFCC... 12 'winlen' 'tstep' 100 100 0
mfcc2 = selected("MFCC",1)
mfcc1 = selected("MFCC",2)
# include log energy
To DTW... 0.9230769230769231 0.07692307692307693 0 0 0.056 yes yes 1/3 < slope < 3
Find path (band)... 0.1 yes 1 1 2
#To DTW... 1 0 0 0 0.056 yes yes 1/3 < slope < 3
dtw1 = selected("DTW")
select 'tg1'
ni = Get number of intervals... 1
for i to ni
tim'i' = Get end point... 1 'i'
lab'i'$ = Get label of interval... 1 'i'
endfor
select 'dtw1'
lastt = 0
lastnt = 0
for i to ni
t = tim'i'
lpt = Get time along path... 't' Lowest
hpt = Get time along path... 't' Highest
nt'i' = (lpt+hpt)/2
lab$ = lab'i'$
nt = nt'i'
durt=t-lastt
durnt=nt-lastnt
stretch'i'=durnt/durt
stretch = stretch'i'
printline Interval 'lab$' should be stretched 'stretch''tab$'('lastt:3','t:3','durt:3') -> ('lastnt:3','nt:3','durnt:3').
lastt = t
lastnt = nt
endfor
Create DurationTier... empty 0 dur1
lastt = 0
for i to ni
str = stretch'i'
p1 = lastt+0.001
p2 = tim'i'-0.001
#mp = (p2+p1)/2
#Add point... mp str
Add point... p1 str
Add point... p2 str
printline 'p1' 'p2' 'str'
lastt = tim'i'
endfor
dt1=selected("DurationTier")
select 's1'
To Manipulation... 0.01 'minp' 'maxp'
man1=selected("Manipulation")
plus 'dt1'
Replace duration tier
select 'man1'
Get resynthesis (PSOLA)