Warning: file(http://person.sol.lu.se/JohanFrid/webapps/websvn/filedetails.php?repname=newrep&path=%2F.praat-dir%2FIntFundComp2.psc&rev=1): failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found in /var/www/person2.sol.lu.se/JohanFrid/webapps/pmwiki/pmwiki.php(1718) : regexp code on line 1 Warning: implode(): Invalid arguments passed in /var/www/person2.sol.lu.se/JohanFrid/webapps/pmwiki/pmwiki.php(1718) : regexp code on line 1 Johan Frid - A byteful of air | Praat / View contents: Praat browse

Praat


About


Praat is a program for "doing phonetics by computer" created by Paul Boersma. Find out more about it on it's home page.

On this page


Various tips, tricks, scripts and thoughts on Praat. Hide contents

ArtSynth1

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

BeatrootAnalysis

Beatroot analysis


Beatroot by Simon Dixon is a system for beat tracking. Here's a small script for integrating this analysis with Praat.

g=bare 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


ChangeGender

Apparently, this is updated

the manual now advises to use factors of 1.1 and 1/1.1

---

Good tip here.

1. to change a man to a woman, use a formant shift ratio of 1.2 and a new pitch median of 220 Hz.
2. to change a woman to a man, use a formant shift ratio of 0.83 and a new pitch median of 100 Hz.

Concatenate all wavs

Load all wav files in a dir and concatenate recoverably. Save Sound and TextGrid to collection.

fg= conc-all-wavs.psc


DLHFloorCeiling

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'

Draw spectrum and formants

This draws a spectrum with LPC smoothing and formants based on the selection in a TextGridEditor.

fg= TextGridEditor_DrawSpectrumAndFormants.psc

<screenshot ?>


Drawing an F1-F2 plot (to appear...)

/* Not finished */

Some code here.


ExtractAndSaveSounds

# This is developed using praat version 5.3.73
form Extract and save sounds
        sentence Path /home/user
        natural Tier 1
endform

if right$(path$,1) != "/"
        path$=path$+"/"
endif

# uncomment to pre-polulate opbject list
#ss1=Create SpeechSynthesizer: "English", "default"
#To Sound: "This is some text.", "yes"

ns=numberOfSelected("Sound")
ntg=numberOfSelected("TextGrid")
if ns != 1 or ntg != 1
        exit Please select exactly 1 Sound and 1 TextGrid!
endif

s1=selected("Sound")
tg1=selected("TextGrid")

Extract non-empty intervals: tier, "no"

nSounds=numberOfSelected("Sound")

for i from 1 to nSounds
        sels[i] = selected("Sound",i)
endfor

select 's1'

name1$=selected$("Sound")
for i from 1 to nSounds
        selectObject: sels[i]
        name2$=selected$("Sound")
        outName$=path$+name1$+"_"+name2$+".wav"
        Save as WAV file: outName$
        Remove
endfor

F0Statistics

form F0 statistics
        sentence Path /home/user/
        word Extension *.wav
        natural Pitch_floor_(Hz) 75
        natural Pitch_ceiling_(Hz) 600
endform

clearinfo
if right$(path$,1) != "/"
        path$=path$+"/"
endif

searchPattern$=path$+extension$

fl=Create Strings as file list: "fileList", searchPattern$
nStr=Get number of strings

clearinfo
writeInfoLine: "Path: ", path$
appendInfoLine: "Extension: ", extension$

writeInfoLine: newline$,"-----------------------------"
appendInfoLine: "file,f0min,f0max,f0mean,f0std"

for i from 1 to nStr
        select 'fl'
        current$=Get string: i
        filename$=path$+current$
        s1=Read from file... 'filename$'
        #tmp1 = i mod 100
        #tmp2 = tmp1+10
        #if tmp2=10
        #       p1=To Pitch: 0, pitch_floor, pitch_ceiling
        #else
                p1=noprogress To Pitch: 0, pitch_floor, pitch_ceiling
        #endif

        minp=Get minimum: 0, 0, "Hertz", "Parabolic"
        maxp=Get maximum: 0, 0, "Hertz", "Parabolic"
        mean=Get mean: 0, 0, "Hertz"
        std=Get standard deviation: 0, 0, "Hertz"

        appendInfoLine: current$,",",'minp:0',",",'maxp:0',",",'mean:3',",",'std:3'

        plus 's1'
        Remove
endfor

select 'fl'
Remove

F1F2-plot from TextGridEditor

This draws a Bark scaled F1/F2-plot based on an annotated waveform. Other scales are possible as well.

fg= editor_f1f2.psc


Generating cropped PNG files from Praat EPS

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: g=php3 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:

g=php3 gs -sDEVICE=png16m -dTextAlphaBits=4 -dEPSCrop -r120 -dSAFER -dBATCH -dNOPAUSE -sOutputFile=$soundDir/$pngFile2 -q $soundDir/$epsFile

See a demo here: mbrola.php


Harmonicity

(just a sketch) fg= harm.psc


Intensity of fundamental component

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.

fg= IntFundComp.psc


Test of websvn display:



IPA label based on shortest formant distance

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.

fg= ipabest_formant_distance.psc


PosDataAnalyzer

PosDataAnalyzer


Quite lengthy script for analysing pos data from the ag500. Lets you focus in on a part of the waveform and then plot a trace of the sensord in the picture window. Extensive use of demo window for interactivity. Lots of undo associated with drawing in the picture window.

form Pos data analyzer
        sentence majorPath X:\Lingvistik\FONM23\articulatory_data
        word minorPath SPTE_xxxx
        natural currentSweep 10
        comment Plot boundaries (please set sensible values here)
        integer left_X_boundaries -80
        integer right_X_boundaries 80
        integer left_Y_boundaries -80
        integer right_Y_boundaries 80
        comment Channel options
        word TT_Channel Ch1
        word TD_Channel Ch2
        word UL_Channel Ch3
        word LL_Channel Ch4
        #sentence Categories HAT/HET/HIT/HUT/HUT/HYT/HÅT/HÄT/HÖT
endform
nocheck select all
nocheck Remove
Erase all

#currentSweep=10
#majorPath$="C:\Users\ling-jfr\Downloads\artuculatory_data"
#minorPath$="SPTE_sara"
artX1=left_X_boundaries
artX2=right_X_boundaries
artY1=left_Y_boundaries
artY2=right_Y_boundaries
ttChX$=tT_Channel$+"_X"
tdChX$=tD_Channel$+"_X"
ulChX$=uL_Channel$+"_X"
llChX$=lL_Channel$+"_X"
ttChZ$=tT_Channel$+"_Z"
tdChZ$=tD_Channel$+"_Z"
ulChZ$=uL_Channel$+"_Z"
llChZ$=lL_Channel$+"_Z"
wavTop=100
wavBottom=80
specTop=80
specBottom=40
garnish$="yes"
analyzed=0

# uncommented to get sane syntax highlighting
#if windows
#  separator$ = "\"
#else
#  separator$ = "/"
#endif

timeRange1=0
timeRange2=0
logName$=majorPath$+separator$+minorPath$+separator$+"pda_"+replace_regex$(date$ (),"[ :]", "_",0)+".log"
#call split "'categories$'" /
#printline 'split.arr$[1]'
goto GETDATA

label CLEANDATA
select 's1'
plus 'spec1'
plus 't1'
plus 'tor2'
Remove
goto GETDATA

label GETDATA
sweepAsString$=right$("000"+"'currentSweep'",4)
wavName$=majorPath$+separator$+minorPath$+separator$+"wav"+separator$+sweepAsString$+".wav"
posName$=majorPath$+separator$+minorPath$+separator$+"pos"+separator$+sweepAsString$+".txt"
#s1=Read from file... C:\Users\ling-jfr\Downloads\artuculatory_data\SPTE_sara\wav\0011.wav
s1=Read from file... 'wavName$'
soundDur=Get total duration
timeRange1=0
timeRange2=soundDur
spec1=noprogress To Spectrogram... 0.005 5000 0.002 20 Gaussian
# articulatory data
#t1=Read Table from tab-separated file... C:\Users\ling-jfr\Downloads\artuculatory_data\SPTE_sara\pos\0011.txt
t1=Read Table from tab-separated file... 'posName$'
tor1=Down to TableOfReal... 0
#tor2=tor1

# low pass filter
nCol=Get number of columns
for i from 1 to nCol
        colLab'i'$=Get column label... i
endfor

m1=To Matrix
m2=Transpose
s2=To Sound
Scale times to... 0 1
Override sampling frequency... 200
s3=Filter (pass Hann band)... 0 10 1
m3=Down to Matrix
m4=Transpose
tor2=To TableOfReal
for i from 1 to nCol
        current$=colLab'i'$
        Set column label (index)... i 'current$'
endfor

select 'tor1'
plus 'm1'
plus 'm2'
plus 's2'
plus 's3'
plus 'm3'
plus 'm4'
Remove

goto REDRAW

label REDRAW
demo Erase all
demo Select outer viewport... 0 100 0 100
demo Axes... 0 100 0 100
demo Black
demo Line width... 1
demo Solid line

# Title
demo Text... 50 centre 100 top 'sweepAsString$'

# buttons
call DrawButton 0 20 12 18 Play
call DrawButton 25 45 12 18 Analyze
call DrawButton 50 70 12 18 Undo
call DrawButton 75 95 12 18 Next

call DrawButton 12 32 24 30 Left
call DrawButton 37 58 28 34 Zoom in
call DrawButton 37 58 20 26 Zoom out
call DrawButton 63 83 24 30 Right

procedure DrawButton .leftX .rightX .topY .bottomY .buttonText$
        demo Paint rectangle... pink .leftX .rightX .topY .bottomY
        demo Draw rectangle... .leftX .rightX .topY .bottomY
        .textX = (.rightX + .leftX) / 2
        .textY = (.topY + .bottomY) / 2
        demo Text... .textX centre .textY half '.buttonText$'
endproc

# waveform
demo Select outer viewport... 0 100 'wavBottom' 'wavTop'
select 's1'
demo Draw... timeRange1 timeRange2 0 0 yes Curve

# spectrogram
demo Select outer viewport... 0 100 'specBottom' 'specTop'
select 'spec1'
demo Paint... timeRange1 timeRange2 0 0 100 yes 50 6 0 yes

myDemoX1=timeRange1
myDemoX2=timeRange1
currentMark=1
goto MARK

label WAIT
while demoWaitForInput ( )
        if demoClicked ( )
                demo Select outer viewport... 0 100 0 100
                demo Axes... 0 100 0 100
                goto PLAY demoClickedIn (0, 20, 12, 18)
                goto ANALYZE demoClickedIn (25, 45, 12, 18)
                goto UNDO demoClickedIn (50, 70, 12, 18)
                goto NEXT demoClickedIn (75, 95, 12, 18)

                goto VIEWLEFT demoClickedIn (12, 32, 24, 30)
                goto ZOOMIN demoClickedIn (37, 58, 28, 34)
                goto ZOOMOUT demoClickedIn (37, 58, 20, 26)
                goto VIEWRIGHT demoClickedIn (63, 83, 24, 30)

                demo Undo

                demo Select outer viewport... 0 100 'specBottom' 'specTop'
                demo Axes... 0 'soundDur' 0 5000
                goto GETMOUSEX demoClickedIn (0, soundDur, 0, 5000)
                demo Undo
        endif
        #goto GETMOUSEX demoClickedIn (0, soundDur, 0, 5000)
        #goto PLAY demoClickedIn
        #goto MARKLEFT demoInput ("1")
        #goto MARKRIGHT demoInput ("2")
        goto EXIT demoInput ("x")
endwhile

label ZOOMIN
demo Undo
viewDur=timeRange2-timeRange1
viewCenter=(timeRange2+timeRange1)/2
viewDur=viewDur*0.5
timeRange1=viewCenter-(viewDur/2)
timeRange2=viewCenter+(viewDur/2)
goto REDRAW

label ZOOMOUT
demo Undo
viewDur=timeRange2-timeRange1
viewCenter=(timeRange2+timeRange1)/2
viewDur=viewDur*2
timeRange1=viewCenter-(viewDur/2)
timeRange2=viewCenter+(viewDur/2)
if timeRange1<0.001
        timeRange1=0
endif
if timeRange2>soundDur
        timeRange2=soundDur
endif
goto REDRAW

label VIEWLEFT
demo Undo
moveDelta=1
if timeRange1<moveDelta
        moveDelta=timeRange1
endif
timeRange1=timeRange1-moveDelta
timeRange2=timeRange2-moveDelta
goto REDRAW

label VIEWRIGHT
demo Undo
moveDelta=1
if timeRange2>soundDur-moveDelta
        moveDelta=soundDur-timeRange2
endif
timeRange1=timeRange1+moveDelta
timeRange2=timeRange2+moveDelta
goto REDRAW

label NEXT
demo Undo
currentSweep=currentSweep+1
goto CLEANDATA

label PLAY
demo Undo
#printline play 'myDemoX1' 'myDemoX2'
# check
if myDemoX1 == 0 && myDemoX2 == 0
        goto WAIT
endif
if (myDemoX1 < myDemoX2)
        mySoundSamp1 = myDemoX1
        mySoundSamp2 = myDemoX2
else
        mySoundSamp1 = myDemoX2
        mySoundSamp2 = myDemoX1
endif
select 's1'
s2=Extract part... mySoundSamp1 mySoundSamp2 rectangular 1 no
Play
Remove
goto WAIT

label UNDO
demo Undo
Undo
Undo
Undo
Undo
Undo
Undo
Undo
Undo
#printline undo
analyzed=analyzed-1
if analyzed<0
        analyzed=0
endif
if analyzed=0
        garnish$="yes"
endif
goto WAIT

label EXIT
demo Select outer viewport... 0 100 0 100
demo Axes... 0 100 0 100
demo Text... 50 centre 0 bottom Script has finished. Please close this window manually...
#printline out of while
exit

label GETMOUSEX
demo Undo

demo Undo
demo Undo
demo Undo
demo Undo
demo Undo
if currentMark==1
        myDemoX1=demoX ( )
        currentMark=2
else
        myDemoX2=demoX ( )
        currentMark=1
endif
goto MARK

label MARK
demo Red
demo Dashed line
demo Line width... 2
demo Draw line... myDemoX1 0 myDemoX1 5000
demo Draw line... myDemoX2 0 myDemoX2 5000
goto WAIT

label ANALYZE
demo Undo
#printline analyze 'myDemoX1' 'myDemoX2'
# check
if myDemoX1 == 0 || myDemoX2 == 0
        goto WAIT
endif
if (myDemoX1 < myDemoX2)
        mySamp1 = floor(myDemoX1 * 200)
        mySamp2 = ceiling(myDemoX2 * 200)
else
        mySamp1 = floor(myDemoX2 * 200)
        mySamp2 = ceiling(myDemoX1 * 200)
endif
select 'tor2'
tor3=Extract row ranges... 'mySamp1':'mySamp2'
t2=To Table...
Append column... labelColumn
nRow=Get number of rows
for i from 1 to nRow
        Set string value... i labelColumn +
endfor
Set string value... 1 labelColumn S
Set string value... nRow labelColumn E

# plot
Blue
Scatter plot... 'ttChX$' artX1 artX2 'ttChZ$' artY1 artY2 labelColumn 12 'garnish$'
garnish$="no"
Red
Scatter plot... 'tdChX$' artX1 artX2 'tdChZ$' artY1 artY2 labelColumn 12 'garnish$'
Green
Scatter plot... 'ulChX$' artX1 artX2 'ulChZ$' artY1 artY2 labelColumn 12 'garnish$'
Purple
Scatter plot... 'llChX$' artX1 artX2 'llChZ$' artY1 artY2 labelColumn 12 'garnish$'

ttxMed=Get quantile... 'ttChX$' 0.5
ttzMed=Get quantile... 'ttChZ$' 0.5
tdxMed=Get quantile... 'tdChX$' 0.5
tdzMed=Get quantile... 'tdChZ$' 0.5
ulxMed=Get quantile... 'ulChX$' 0.5
ulzMed=Get quantile... 'ulChZ$' 0.5
llxMed=Get quantile... 'llChX$' 0.5
llzMed=Get quantile... 'llChZ$' 0.5
time1=mySamp1/200
time2=mySamp2/200
printline 'time1:3''tab$''time2:3''tab$''ttxMed:3''tab$''ttzMed:3''tab$''tdxMed:3''tab$''tdzMed:3''tab$''ulxMed:3''tab$''ulzMed:3''tab$''llxMed:3''tab$''llzMed:3'
fileappend 'logName$' 'time1:3''tab$''time2:3''tab$''ttxMed:3''tab$''ttzMed:3''tab$''tdxMed:3''tab$''tdzMed:3''tab$''ulxMed:3''tab$''ulzMed:3''tab$''llxMed:3''tab$''llzMed:3''newline$'



analyzed=analyzed+1

plus 'tor3'
Remove
goto WAIT

procedure split .str$ .delimiter$
        .num = 1
        .arr$[.num] = .str$
        repeat
                .lastValue$ = .arr$[.num]
                .delimiterPos = index_regex(.lastValue$,.delimiter$)
                if .delimiterPos <> 0
                        .arr$[.num] = left$(.lastValue$,.delimiterPos-1)
                        .num += 1
                        .arr$[.num] = replace_regex$(right$(.lastValue$,length(.lastValue$)-.delimiterPos+1),.delimiter$,"",1)
                endif
        until .delimiterPos = 0
endproc

Screenshots (on google drive)


Reaction time analyzer

Reaction time analyzer


Script used to estimate voice activity. Use of the demo window to run through lots of files. Some tricks to detect steepest rise.

#form Reaction time analyzer
#       sentence majorPath C:\Users\ling-jfr\Dropbox\Atttittapådata
#       natural currentSweep 1
#endform

# commented to get sane syntax highlighing in the wiki
#majorPath$="C:\Users\ling-jfr\Dropbox\Atttittapådata"
##anaFile$="C:\Users\ling-jfr\Dropbox\Atttittapådata\analysis.txt"
#anaFile$="C:\Users\ling-jfr\Documents\Praat\analysis.txt"
createAnalysisFile=0

nocheck select all
nocheck Remove
Erase all
#clearinfo

currentSweep=1
# find unanalyzed
if fileReadable(anaFile$)
        anaStrings=Read from file... 'anaFile$'
        numStr=Get number of strings
        for i from 1 to numStr
                cStr$=Get string... i
                if cStr$=="false"
                        currentSweep=i
                        i=numStr
                endif
        endfor
endif
#currentSweep=1

wavTop=95
wavBottom=65
specTop=70
specBottom=40
garnish$="yes"
analyzed=0

# commented to get sane syntax highlighing in the wiki
#if windows
#  separator$ = "\"
#else
#  separator$ = "/"
#endif

timeRange1=0
timeRange2=0

# create notch filter
#lowSteep = sqrt(ln(2))
#lowFreq = 430
#beta = sqrt(ln(2))
#highFreq = 2000
#filterSound=Create Sound from formula... filter 1 -0.2 0.2 44100 2*pi*sqrt(pi)*highFreq/beta*exp(-(pi*x*highFreq/beta)^2) - 4*pi*sqrt(pi)*lowFreq/lowSteep*exp(-(pi*x*lowFreq/lowSteep)^2)

# lpc filter
lpcfilter=Read from file... C:\Users\ling-jfr\Dropbox\Atttittapådata\lpcfilter.LPC

# run through dir and subdirs and look for wavs
# store them in Strings object wavStrings
dirWithWavs=0
dirGlobPath$=majorPath$+separator$+"*"
strings1 = Create Strings as directory list... directoryList1 'dirGlobPath$'
nStrings1=Get number of strings
for i from 1 to nStrings1
        select 'strings1'
        currentStringi$=Get string... i
        subDirGlobPath$=majorPath$+separator$+currentStringi$
        strings2 = Create Strings as directory list... directoryList2 'subDirGlobPath$'
        nStrings2=Get number of strings
        for j from 1 to nStrings2
                select 'strings2'
                currentStringj$=Get string... j
                wavGlobPath$=subDirGlobPath$+separator$+currentStringj$+separator$+"*.wav"
                strings3 = Create Strings as file list... fileList 'wavGlobPath$'
                nStrings3=Get number of strings
                for k from 1 to nStrings3
                        select 'strings3'
                        currentStringk$=Get string... k
                        wavName$=subDirGlobPath$+separator$+currentStringj$+separator$+currentStringk$
                        Set string... k 'wavName$'
                endfor

                if nStrings3 > 0
                        dirWithWavs=dirWithWavs+1
                endif
                if dirWithWavs==1
                        select 'strings3'
                        Copy... appended
                        wavStrings=selected("Strings")
                endif
                if dirWithWavs > 1
                        select 'wavStrings'
                        plus 'strings3'
                        newWavStrings=Append
                        select 'wavStrings'
                        Remove
                        select 'newWavStrings'
                        wavStrings=selected("Strings")
                endif
                select 'strings3'
                Remove
        endfor
        select 'strings2'
        Remove
endfor
select 'strings1'
Remove

select 'wavStrings'
numWav=Get number of strings
# we should save the wavStrings with the anaFile so
# we're safe if the wav structure is changed

# create an analysis file
if createAnalysisFile
        for i from 1 to numWav
                Set string... i false
        endfor
        Save as short text file... 'anaFile$'
        exit
endif

goto GETDATA

label CLEANDATA
select 's1'
plus 's2'
plus 's4'
plus 'spec1'
plus 'i1'
plus 'tg1'
Remove
goto GETDATA

label GETDATA
select 'wavStrings'
currentStringi$=Get string... currentSweep
s1=Read from file... 'currentStringi$'
startSound = Get start time
endSound = Get end time
startIv = startSound
endIv = endSound
durIv = endIv - startIv
plus 'lpcfilter'
s4=Filter (inverse)
Scale intensity... 70
spec1=noprogress To Spectrogram... 0.005 5000 0.002 20 Gaussian
select 's4'
s2=noprogress Deepen band modulation... 20 300 8000 3 30 100
Scale intensity... 70

select 's2'
i1=To Intensity... 75 0 yes
Formula... if x < 0.2 || x > 1.5 then 0 else self fi

keep = 0
noMoreCheck = 0
numberOfLevels = 5
for i from 1 to numberOfLevels
        thresh = -5-(i*5)
        select 'i1'
        tg'i' = To TextGrid (silences)... thresh 0.1 0.12 silent sounding
        countSounding=Count labels... 1 sounding
        if countSounding > 1 && keep > 0
                noMoreCheck=1          
        endif
        if countSounding == 1 && noMoreCheck == 0
                if i > 1
                        lastDurIv = durIv
                endif
                call GetBounds
                if i > 1
                        tIncrease = durIv / lastDurIv
                else
                        tIncrease = 1
                endif
                keep = i

#               # prevent overlong increase between 20 and 25
#               if i == 4
#                       printline overlong increase 'currentSweep' 'i': ('tIncrease')
#                       if tIncrease > 1.25
#                               keep = 3
#                               noMoreCheck = 1
#                               printline overlong increase 'currentSweep' 'i': ('tIncrease')
#                       else
#                               keep = 4
#                       endif
#               endif


                # prevent overlong increase between 25 and 30
                if i == 5
                        if tIncrease > 1.5
                                keep = 4
                                noMoreCheck = 1
#                               printline overlong increase 'currentSweep' 'i': ('tIncrease')
                        else
                                keep = 5
                        endif
                endif
        endif
endfor

if keep > 0
        dum = tg'keep'
        select 'dum'
        tgfin = Copy...
else
        select 'i1'
        tgfin = To TextGrid (silences)... -200 0.1 0.1 silent sounding
endif

select 'tg1'
for i from 2 to numberOfLevels
        dum = tg'i'
        plus 'dum'
endfor
Remove

select 'tgfin'
tg1=selected("TextGrid")

select 'i1'
call findRise
tg2=selected("TextGrid")
plus 'tg1'
tgboth=Merge
select 'tg1'
plus 'tg2'
Remove
select 'tgboth'
tg1=selected("TextGrid")


startIv = startSound
endIv = endSound
durIv = endIv - startIv
call GetBounds
goto REDRAW

procedure GetBounds
#indent
nInt=Get number of intervals... 1
for .i from 1 to nInt
        lab$=Get label of interval... 1 .i
        if lab$=="sounding"
                startIv=Get start point... 1 .i
                endIv=Get end point... 1 .i
                durIv = endIv - startIv
        endif
endfor
select 'i1'
dbAtStartIv=Get value at time... startIv Cubic
#indent
endproc


label REDRAW
demo Erase all
demo Select outer viewport... 0 100 0 100
demo Axes... 0 100 0 100
demo Black
demo Line width... 1
demo Solid line

# Title
demo Text... 50 centre 100 top 'currentStringi$' ('currentSweep'/'numWav')

# buttons
call DrawButton 0 20 12 18 Prev
call DrawButton 25 45 12 18 Reject
call DrawButton 50 70 12 18 Accept
call DrawButton 75 95 12 18 Next

call DrawButton 12 32 24 30 Target
call DrawButton 37 58 28 34 Before
call DrawButton 37 58 20 26 After
call DrawButton 63 83 24 30 All

procedure DrawButton .leftX .rightX .topY .bottomY .buttonText$
        demo Paint rectangle... pink .leftX .rightX .topY .bottomY
        demo Draw rectangle... .leftX .rightX .topY .bottomY
        .textX = (.rightX + .leftX) / 2
        .textY = (.topY + .bottomY) / 2
        demo Text... .textX centre .textY half '.buttonText$'
endproc

# waveform
demo Select outer viewport... 0 100 'wavBottom' 'wavTop'
select 's4'
plus 'tg1'
demo Draw... timeRange1 timeRange2 yes yes yes
demo Red
demo Solid line
demo Line width... 3
demo Draw rounded rectangle... startIv endIv 1 -1 3
demo Line width... 1

# spectrogram
demo Select outer viewport... 0 100 'specBottom' 'specTop'
select 'spec1'
demo Paint... timeRange1 timeRange2 0 0 100 yes 50 6 0 yes
select 'i1'
demo Line width... 2
demo Draw... timeRange1 timeRange2 0 0 no

myDemoX1=timeRange1
myDemoX2=timeRange1
currentMark=1
goto WAIT

label WAIT
while demoWaitForInput ( )
        if demoClicked ( )
                demo Select outer viewport... 0 100 0 100
                demo Axes... 0 100 0 100
                goto PREV demoClickedIn (0, 20, 12, 18)
                goto REJECT demoClickedIn (25, 45, 12, 18)
                goto ACCEPT demoClickedIn (50, 70, 12, 18)
                goto NEXT demoClickedIn (75, 95, 12, 18)

                goto PLAYTARGET demoClickedIn (12, 32, 24, 30)
                goto PLAYBEFORE demoClickedIn (37, 58, 28, 34)
                goto PLAYAFTER demoClickedIn (37, 58, 20, 26)
                goto PLAYALL demoClickedIn (63, 83, 24, 30)

                #demo Undo

                #demo Select outer viewport... 0 100 'specBottom' 'specTop'
                #demo Axes... 0 'soundDur' 0 5000
                #goto GETMOUSEX demoClickedIn (0, soundDur, 0, 5000)
                #demo Undo
        endif
        #goto GETMOUSEX demoClickedIn (0, soundDur, 0, 5000)
        #goto PLAY demoClickedIn
        #goto MARKLEFT demoInput ("1")
        #goto MARKRIGHT demoInput ("2")
        goto EXIT demoInput ("x")
        goto ACCEPT demoInput (" ")
        goto REJECT demoInput ("r")
        goto PLAYTARGET demoInput ("t")
        goto PLAYALL demoInput ("a")
        goto ERROR demoInput("e")
endwhile
pause Why are we here?

label ACCEPT
select 'anaStrings'
Set string... currentSweep 'startIv:3'
Save as short text file... 'anaFile$'
goto NEXT

label REJECT
select 'anaStrings'
Set string... currentSweep reject
Save as short text file... 'anaFile$'
goto NEXT

label ERROR
select 'anaStrings'
Set string... currentSweep error
Save as short text file... 'anaFile$'
goto NEXT

label NEXT
#demo Undo
currentSweep=currentSweep+1
goto CLEANDATA

label PREV
#demo Undo
currentSweep=currentSweep-1
goto CLEANDATA

label EXIT
demo Select outer viewport... 0 100 0 100
demo Axes... 0 100 0 100
demo Text... 50 centre 0 bottom Script has finished. Please close this window manually...
exit

label PLAYTARGET
startPlay = startIv
endPlay = endIv
goto PLAY

label PLAYBEFORE
startPlay = startSound
endPlay = startIv
goto PLAY

label PLAYAFTER
startPlay = endIv
endPlay = endSound
goto PLAY

label PLAYALL
startPlay = startSound
endPlay = endSound
goto PLAY

label PLAY
select 's4'
s3=Extract part... startPlay endPlay rectangular 1 no
Play
Remove
goto WAIT

# unused
procedure useVoicing
select 's2'
pp1=noprogress To PointProcess (periodic, cc)... 75 600
tg2=To TextGrid (vuv)... 0.02 0.01
nInt=Get number of intervals... 1
myLowest=100
moveTo=0
for i from 1 to nInt
        lab$=Get label of interval... 1 i
        if lab$=="V"
                startVIv=Get start point... 1 i
                diff=abs(startIv-startVIv)
                if diff < myLowest
                        myLowest = diff
                        moveTo=startVIv
                endif  
        endif
endfor
startIv=moveTo

plus 'tg1'
tgboth=Merge
select 'tg1'
plus 'tg2'
plus 'pp1'
Remove
select 'tgboth'
tg1=selected("TextGrid")
endproc


procedure findRise
        .i1=selected("Intensity")
        .m1=Down to Matrix
        .s1=To Sound
        .pp1=To PointProcess (extrema)... 1 yes no Sinc70
        select '.i1'
        #call Acceleration
        call Curvature
        #call Velocity
        .s2=selected("Sound")
        .pp2=To PointProcess (extrema)... 1 yes no Sinc70
if 1
        np1=Get number of points
        candidateIndex=0
        for cp1 from 1 to np1
                select '.pp2'
                accStartTime=Get time from index... cp1
                if accStartTime > 0.2 && accStartTime < 1.5
                select '.pp1'
                disPeakIndex=Get high index... accStartTime
                if disPeakIndex = undefined
                        # some exceptional action
                else
                        disPeakTime=Get time from index... disPeakIndex
                        if disPeakTime = undefined
                                # some exceptional action
                        else
                                candidateIndex=candidateIndex+1
                                select '.i1'
                                accStartVal=Get value at time... accStartTime Cubic
                                disPeakVal=Get value at time... disPeakTime Cubic
                                valDiff=disPeakVal-accStartVal
                                #printline AccIndex: 'cp1' DisPeakIndex: 'disPeakIndex'
                                #       ... AccStartTime: 'accStartTime:3' DisPeakTime: 'disPeakTime:3'
                                #       ... AccStartVal: 'accStartVal:3' DisPeakVal: 'disPeakVal:3'
                                #       ... ValDiff: 'valDiff:3'
                                sTime'candidateIndex'=accStartTime
                                eTime'candidateIndex'=disPeakTime      
                                valD'candidateIndex'=valDiff
                        endif
                endif
                endif
        endfor
endif


if 1
        max=0
        indexOfMax=0
        for cCand from 1 to candidateIndex
                if valD'cCand'>=max
                        max = valD'cCand'
                        indexOfMax=cCand
                endif
        endfor
        select '.s1'
        .tg1=To TextGrid... rise
        Insert boundary... 1 sTime'indexOfMax'
        Insert boundary... 1 eTime'indexOfMax'
        Set interval text... 1 2 rise
endif

        select '.pp2'
        plus '.s2'
        plus '.pp1'
        plus '.s1'
        plus '.m1'
        Remove
        select '.tg1'
endproc

procedure Curvature
        .m1=Down to Matrix
        Rename... '.m1'
        .m2=Copy... Velocity
        Rename... '.m2'
        Formula... (Matrix_'.m1'[col+1]-Matrix_'.m1'[col-1])/2*dx
        Formula... if col == 1 || col == ncol then 0 else self fi
        .m3=Copy... Acceleration
        Rename... '.m3'
        Formula... (Matrix_'.m2'[col+1]-Matrix_'.m2'[col-1])/2*dx
        Formula... if col == 1 || col == ncol then 0 else self fi
        select '.m1'
        Formula... Matrix_'.m3'[col]/(1+Matrix_'.m2'[col]^2)^1.5
        .s1=To Sound
        Rename... '.s1'
        select '.m1'
        plus '.m2'
        plus '.m3'
        Remove
        select '.s1'
endproc

Screenshot (at google drive)


ReadWavAndTG

g=praat # 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


Syllabifier

This is somewhat mad: first do phone recognition using sphinx, then syllabify using syllabify.py. Works pretty well, even for Swedish!

There were a few hurdles in getting sphinx to run, but it boiled down to using the correct version of sphinxbase and sphinx3 as mentioned here.

I built my own language model using lmtool, see info here. This was based on ked_timit + some of the arctic databases. This seems to work better for short sentences of read-type speech.

#nocheck select all
#nocheck Remove

sphinxDir$="~/OperaDownloads/sphinxtest/"
phonesTier=1
sylTier=2

include ~/.praat-dir/split.proc.praat

s1 = selected("Sound")
#s1=do ("Read from file...", sphinxDir$+"in.sph")

do ("Save as NIST file...", sphinxDir$+"test.sph")
tg1=do ("To TextGrid...", "sphinx_seg sylls", "")

system sphinx3_decode
... -mode allphone
... -ctl 'sphinxDir$'test.ctl
... -cepdir 'sphinxDir$'
... -cepext .sph
... -adcin yes
... -adchdr 1024
... -hmm /home/johanf/OperaDownloads/sphinx3-0.8/model/hmm/hub4_cd_continuous_8gau_1s_c_d_dd
... -lm 'sphinxDir$'7035.lm
... -dict 'sphinxDir$'7035.dic
... -fdict 'sphinxDir$'filler.dict
... -hypseg 'sphinxDir$'test.lab

#... -lm 'sphinxDir$'7666.lm
#... -lm 'sphinxDir$'interp_nodx.arpa.dmp
# we build our own lm from cmudict


str1=do ("Read Strings from raw text file...", sphinxDir$+"test.lab")
sphinx_str$=Get string... 1

select 'tg1'

writeInfoLine("--sphinx output--")
@split (" ", sphinx_str$)

#for i to split.length
#       str$[i] = split.array$[i]
#       appendInfoLine(i, tab$, str$[i])
#endfor

co=13
labNo=0
sylString$=""
while co < split.length
        lab$ = split.array$[co]
        #if (lab$ != "SIL")
                sylString$=sylString$+lab$+" "
        #endif
        frame = number(split.array$[co+1])*0.01

        labNo=labNo+1
        do ("Insert boundary...", phonesTier, frame)
        do ("Set interval text...", phonesTier, labNo, lab$)

#       # if first is SIL then add sylbound at end of interval
#       if (labNo==1)
#               do ("Insert boundary...", sylTier, frame)
#       endif

        appendInfoLine(co, tab$, lab$, tab$, frame)
        co = co + 4
endwhile
# if last is SIL then keep a reminder to add sylbound at start of interval
#addLast=0
if (lab$ == "SIL")
#       addLast=1
        addLastTime=do ("Get start point...", phonesTier, labNo)
else
        addLastTime=do ("Get end point...", phonesTier, labNo)
endif

writeFile(sphinxDir$+"phones.txt", sylString$)

system python 'sphinxDir$'syllabifier.py English < 'sphinxDir$'phones.txt > 'sphinxDir$'syllables.txt
syllables$ = readFile$ (sphinxDir$+"syllables.txt")
appendInfoLine(syllables$)
@split (" ", syllables$)

sylIndex=0
for i to split.length
        if (split.array$[i] == "SIL" && i == 1)
                sylTime=do ("Get end point...", phonesTier, 1)
                do ("Insert boundary...", sylTier, sylTime)
        endif
        if (split.array$[i] == ".")
                sylIndex=sylIndex+1
                phoneWithSyl = i - sylIndex
                sylTime=do ("Get end point...", phonesTier, phoneWithSyl)
                do ("Insert boundary...", sylTier, sylTime)
                nInt=do ("Get number of intervals...", sylTier)
                do ("Set interval text...", sylTier, nInt-1, "syl")
        endif
endfor
#if (addLast)
        do ("Insert boundary...", sylTier, addLastTime)
        nInt=do ("Get number of intervals...", sylTier)
        do ("Set interval text...", sylTier, nInt-1, "syl")
#endif 


plusObject (s1)

Vowels


Warp duration

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.

fg= warp_duration.psc


Warp duration using Psola

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.

fg= warp_duration_psola.psc


June 2017
MonTueWedThuFriSatSun
   01020304
05060708091011
12131415161718
19202122232425
2627282930