- The added line is THIS COLOR.
- The deleted line is THIS COLOR.
#freeze
[[FrontPage]]
#counter
#contents
#logparanoia()
* Praat Script Tips [#s823a6ce]
#contents
- To TextGrid
** Emulation of Perl's '''split''' function [#r73a5d35]
- The subscripts start at 0.
- The last subscript is stored in ''lastSub''.
- ''delimiter$'' is specified by a regular expression.
wavFile$ = "C:\sample\sample.wav"
Open long sound file... 'wavFile$'
tierNames$ = "Mary John bell"
pointTiers$ = "bell"
# This does NOT work!
#To TextGrid... "'tierNames$'" "'pointTiers$'"
# Instead, ...
To TextGrid... "'tierNames$'" " 'pointTiers$' "
Edit
string$ = "hoge/piyo/foo/bar"
delimiter$ = "/"
- When you prompt the user to specify a particular folder/directory in the form, it might be better to write a script in which the path separator is complemented if necessary, regardless of the platform.
-- Sample Script:
filename$ = "hoge.TextGrid"
if index_regex("",delimiter$) = 1
lastSub = length(string$)-1
for i from 0 to lastSub
arr$[i] = mid$(string$,i+1,1)
endfor
form Specify the folder
sentence dir c:\foo\bar
endform
if windows = 1
pathSep$ = "\"
elsif macintosh + unix >= 1
pathSep$ = "/"
else
lastSub = 0
arr$[0] = string$
repeat
lastValue$ = arr$[lastSub]
delimiterPos = index_regex(lastValue$,delimiter$)
if delimiterPos <> 0
arr$[lastSub] = left$(lastValue$,delimiterPos-1)
lastSub = lastSub+1
arr$[lastSub] = replace_regex$(right$(lastValue$,length(lastValue$)-delimiterPos+1),delimiter$,"",1)
endif
until delimiterPos = 0
exit sorry. Unknown platform.
endif
if endsWith(dir$,pathSep$) = 0
dir$ = dir$ + pathSep$
endif
echo 'dir$''filename$'
- If you make some modifications to a TextGrid tier which may cause the change of the total number of the intervals/points, it would be better to manipulate it form the last to the first (rather than the first to the last), so as to the index of the current interval/point is kept constant while processing.
-- Sample TextGrid: &ref(sample_concat.TextGrid);
-- Sample Script: Concatenate intervals to the right if the labels end with ''concatSymbol$''.
# concat intervals to the right
# if the label ends with concatSymbol$
concatSymbol$ = "+"
targetTierNum = 1
n = Get number of intervals... 'targetTierNum'
n = n-1
while n >= 1
currentLabel$ = Get label of interval... 'targetTierNum' n
if endsWith(currentLabel$,concatSymbol$) = 1
# currentLabel$ = currentLabel$ - concatSymbol$
# Set interval text... 'targetTierNum' n 'currentLabel$'
Remove right boundary... 'targetTierNum' n
endif
n = n-1
endwhile
-- '''Cf'''. Bad Script (an error occurs)
# BAD SCRIPT (from the first to the last)
# This does not work!
concatSymbol$ = "+"
targetTierNum = 1
n = Get number of intervals... 'targetTierNum'
for i from 1 to n-1
currentLabel$ = Get label of interval... 'targetTierNum' i
if endsWith(currentLabel$,concatSymbol$) = 1
# currentLabel$ = currentLabel$ - concatSymbol$
# Set interval text... 'targetTierNum' i 'currentLabel$'
Remove right boundary... 'targetTierNum' i
endif
endfor
* Small but Complete Scripts [#dcae7a2c]
//- My primary interest is corpus annotation, rather than acoustic analysis. So, most scripts concern the former.
- The scripts presented below are of little use per se.
- It is easy to see, however, how they work.
//- Most of them works at all.
** deselect_all [#q9e68840]
call deselect_all
procedure deselect_all
.n = numberOfSelected()
for .i to .n
.objID[.i] = selected(.i)
endfor
for .i to .n
.curObjID = .objID[.i]
minus .curObjID
endfor
endproc
** Get the start and end time of the selected region on the TextGridEditor [#x005cb78]
# Before executing this script, select a TextGrid Object in advance.
filebasename$ = selected$("TextGrid")
editor TextGrid 'filebasename$'
selStart = Get begin of selection
selEnd = Get end of selection
endeditor
echo 'filebasename$''tab$''selStart''tab$''selEnd'
** Sort the indices of an array by the values [#vfa5a204]
arr[1] = 5.2
arr[2] = 2
arr[3] = 4
arr[4] = 1.53
lastSub = 4
## Use Table Object ##
tableName$ = "tmp4srt"
tableColName1$ = "index"
tableColName2$ = "value"
Create Table with column names... 'tableName$' lastSub 'tableColName1$' 'tableColName2$'
for i to lastSub
Set numeric value... i 'tableColName1$' i
Set numeric value... i 'tableColName2$' arr[i]
endfor
Sort rows... 'tableColName2$'
for i to lastSub
newarr[i] = Get value... i 'tableColName1$'
endfor
Remove
clearinfo
for i from 0 to lastSub
hop$ = arr$[i]
printline 'i''tab$''hop$'
for i to lastSub
hop = newarr[i]
printline 'hop'
endfor
- Result:
0 hoge
1 piyo
2 foo
3 bar
4
2
3
1
- '''Cf.''' Equivalent Perl Script:
** Sort the values of an array [#h4dd9c7c]
$string = "hoge/piyo/foo/bar";
$delimiter = "/";
arr[1] = 5.2
arr[2] = 2
arr[3] = 4
arr[4] = 1.53
lastSub = 4
@arr = split(/$delimiter/,$string);
## Use Table Object ##
for ( $i = 0 ; $i <= $#arr ; $i++ ) {
print "$i\t$arr[$i]\n";
}
tableName$ = "tmp4srt"
tableColName$ = "num"
Create Table with column names... 'tableName$' lastSub 'tableColName$'
for i to lastSub
Set numeric value... i 'tableColName$' arr[i]
endfor
Sort rows... 'tableColName$'
for i to lastSub
newarr[i] = Get value... i 'tableColName$'
endfor
Remove
clearinfo
for i to lastSub
hop = newarr[i]
printline 'hop'
endfor
- Result:
1.53
2
4
5.2
** Emulation of Perl's $`, $&, and $' [#z1b70bdd]
- Extract the substring matched with a regular expression.
string$ = "abcdefg"
regex$ = "b[^e]*"
prematch$ = ""
match$ = ""
postmatch$ = ""
pos = index_regex(string$,regex$)
if pos <> 0
prematch$ = left$(string$,pos-1)
match$ = right$(string$,length(string$)-pos+1)
postmatch$ = replace_regex$(match$,regex$,"",1)
match$ = match$ - postmatch$
endif
clearinfo
printline 'prematch$''tab$''match$''tab$''postmatch$'
- Result:
a bcd efg
- '''Cf.''' An equivalent perl script:
$string = "abcdefg";
$regex = "b[^e]*";
$string =~ m/$regex/;
print "$`\t$&\t$'\n";
** Emulation of Perl's '''split''' function [#r73a5d35]
&color(red){Modified July 24, 2012. It still has a bug, however};((About the bug in [[the emulation of ''split''>#r73a5d35]]. When you specify a regular expression which can match the null string "", say "/*", as the delimiter, the '''greedy''' property does not work, and the result contains substrings which also match the delimiter ("/", in the case where "/*" is specified as the delimiter). Apparently, the command in line 5 (''replace_regex$'') is not working as expected. (Check the value of ''replace_regex$("foo/bar","/*","",0)'' on your Praat. Check also: ''perl -e '{$str="foo/bar";$str=~s|/*||g;print "$str\n";}' '') )).
call split "str" delimiter
- The subscripts start at 1.
- The last subscript is stored in ''split.num''.
- Each values are stored in ''split.arr$[n]''.
- ''delimiter$'' must NOT be enclosed with double quotations.
- ''delimiter$'' is specified by a regular expression.
clearinfo
foo$ = "hoge/piyo/foo/bar"
call split "'foo$'" /
for i to split.num
hop$ = split.arr$[i]
printline 'i''tab$''hop$'
endfor
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
- Result:
1 hoge
2 piyo
3 foo
4 bar
- See also:
-- http://www.fon.hum.uva.nl/praat/manual/Scripting_5_6__Arrays.html
** Check your Praat Version [#kab1ed91]
requiredVersion = 5209
# commas omitted (the above means "version 5.2.09")
if praatVersion < requiredVersion
exit Your Praat (Version 'praatVersion') is too old. Use Version 'requiredVersion' or newer.
endif
- See also:
-- http://www.fon.hum.uva.nl/praat/manual/Scripting_5_1__Variables.html (for predefined numeric variables)
** Get the path separator for your platform [#wa2b03b8]
- Get the path separator for your platform, and
- Rewrite the path.
-- Useful especially on Cygwin.
-- You can write a script which works on any platforms.
//Useful especially if you use Cygwin.
input$ = "c:/foo/bar/hoge.TextGrid"
output$ = "c:/foo/bar/result"
#input$ = "c:\foo\bar\hoge.TextGrid"
#output$ = "c:\foo\bar\result"
if windows = 1
pathSep$ = "\"
notPathSep$ = "/"
elsif macintosh + unix >= 1
pathSep$ = "/"
notPathSep$ = "\"
else
exit Sorry. Unknown platform.
endif
input$ = replace$(input$,notPathSep$,pathSep$,0)
output$ = replace$(output$,notPathSep$,pathSep$,0)
clearinfo
printline 'input$'
printline 'output$'
- Result (using Windows Praat on Cygwin):
c:\foo\bar\hoge.TextGrid
c:\foo\bar\result
- See also:
-- http://www.fon.hum.uva.nl/praat/manual/Scripting_5_1__Variables.html (for predefined numeric variables)
** Get the path and filename from a string [#m2fcc07d]
dir$ = "c:/hoge/piyo/foo.TextGrid"
#dir$ = "c:\hoge\piyo\foo.TextGrid"
if windows + macintosh + unix = 0
exit Sorry. Unknown platform.
endif
path$ = left$(dir$,rindex_regex(dir$,"[/\\]"))
filename$ = right$(dir$,length(dir$)-rindex_regex(dir$,"[/\\]"))
## if you have the path separator (pathSep$) already, you can write:
#path$ = left$(dir$,rindex(dir$,pathSep$))
#filename$ = right$(dir$,length(dir$)-rindex(dir$,pathSep$))
clearinfo
printline 'path$'
printline 'filename$'
- Result:
c:/hoge/piyo/
foo.TextGrid
** Upper to Lower Case [#idd10905]
str$ = "ABCDEFG"
newstr$ = replace_regex$(str$,"[A-Z]","\L&",0)
echo 'newstr$'
- Result:
abcdefg
- See also:
-- http://uk.groups.yahoo.com/group/praat-users/message/5278
** Get the tiernumbers from the tiernames [#x5d26030]
** Get the tiernumbers from tiernames [#x5d26030]
- If you already know the names of the target tiers (e.g., "Seg," "Word"), ...
file$ = "N:\sample\sample.TextGrid"
select all
Remove
Read from file... 'file$'
segTierNum = 0
wordTierNum = 0
n = Get number of tiers
for i from 1 to n
currentTier$ = Get tier name... i
if currentTier$ = "Seg"
segTierNum = i
elsif currentTier$ = "Word"
wordTierNum = i
endif
endfor
if segTierNum = 0
exit Seg tier not found in 'file$'
elsif wordTierNum = 0
exit Word tier not found in 'file$'
endif
clearinfo
printline Seg tier: 'segTierNum'
printline Word tier: 'wordTierNum'
** Recover the Object List to the previous state [#pbb9b803]
&color(red){Modified May 24, 2011. };
# Before trying this script, make several objects
# on the Object List and select some of them.
selectedObjectNum = numberOfSelected()
for i from 1 to selectedObjectNum
selectedID[i] = selected(i)
endfor
select all
pause All objects are selected. Press "Continue" to recover the previous state.
if selectedObjectNum = 0
Create TextGrid... 0 1 Mary ;; Dummy
Remove
else
select selectedID[1]
for i from 2 to selectedObjectNum
plus selectedID[i]
endfor
endif