- The added line is THIS COLOR.
- The deleted line is THIS COLOR.
#freeze
[[FrontPage]]
#counter
#contents
#logparanoia()
* Praat Script Tips [#s823a6ce]
- To TextGrid
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
- 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"
form Specify the folder
sentence dir c:\foo\bar
endform
if windows = 1
pathSep$ = "\"
elsif macintosh + unix >= 1
pathSep$ = "/"
else
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 below are small and of little use per se.
- 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.
#contents
** 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 to lastSub
hop = newarr[i]
printline 'hop'
endfor
- Result:
4
2
3
1
** Sort the values of an array [#h4dd9c7c]
arr[1] = 5.2
arr[2] = 2
arr[3] = 4
arr[4] = 1.53
lastSub = 4
## Use Table Object ##
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"
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 original : 'string$'
printline : 'prematch$''match$''postmatch$'
printline ==============================
printline regex : 'regex$'
printline ==============================
printline prematch : 'prematch$'
printline match : 'match$'
printline postmatch: 'postmatch$'
printline ==============================
printline 'prematch$''tab$''match$''tab$''postmatch$'
- Result:
original : abcdefg
: abcdefg
==============================
regex : b
==============================
prematch : a
match : b
postmatch: cdefg
==============================
a bcd efg
- '''Cf.''' An equivalent perl script:
$string = "abcdefg";
$regex = "b";
$regex = "b[^e]*";
$string =~ m/$regex/;
print "$`\t$&\t$'\n";
** Check your Praat Version [#kab1ed91]
** 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";}' '') )).
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
call split "str" delimiter
- See also:
-- http://www.fon.hum.uva.nl/praat/manual/Scripting_5_1__Variables.html (for predefined numeric variables)
** Emulation of Perl's '''split''' function [#r73a5d35]
&color(red){Modified May 20, 2011. It still has a bug, however};((About the bug in [[the emulation of ''split''>#r73a5d35]]. When you specify, say "/*", a regular expression which can match the null string "" as the delimiter, the '''greedy''' property does not work, and the result contains substrings which also match the delimiter. Apparently, the command in line 5 (''replace_regex$'') does not work as you expect. (Check the value of ''replace_regex$("foo//bar","/*","",0)'' on your Praat.) )).
- The subscripts start at 0.
- The last subscript is stored in ''lastSub''.
- 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.
string$ = "hoge/piyo/foo/bar"
delimiter$ = "/"
clearinfo
if index_regex("",delimiter$) = 1
tmp$ = replace_regex$(string$,delimiter$,"",0)
lastSub = length(tmp$)-1
for i from 0 to lastSub
arr$[i] = mid$(tmp$,i+1,1)
endfor
else
lastSub = 0
arr$[lastSub] = 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
endif
foo$ = "hoge/piyo/foo/bar"
clearinfo
for i from 0 to lastSub
hop$ = arr$[i]
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
0 hoge
1 piyo
2 foo
3 bar
- See also:
-- http://www.fon.hum.uva.nl/praat/manual/Scripting_5_6__Arrays.html
- '''Cf.''' An equivalent Perl Script:
** Check your Praat Version [#kab1ed91]
$string = "hoge/piyo/foo/bar";
$delimiter = "/";
requiredVersion = 5209
# commas omitted (the above means "version 5.2.09")
@arr = split(/$delimiter/,$string);
for ( $i = 0 ; $i <= $#arr ; $i++ ) {
print "$i\t$arr[$i]\n";
}
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_6__Arrays.html
-- 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.
-- 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 tiernames [#x5d26030]
- If you already know the names of the target tiers (e.g., "Seg," "Word"), ...
file$ = "N:\sample\sample.TextGrid"
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
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