[[FrontPage]] #counter #contents * Praat Script Tips [#s823a6ce] - 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. 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 presented below are of little use per se. - It is easy to see, however, how they work. //- Most of them works at all. ** 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 May 20, 2011. 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";}' '') )). - The subscripts start at 0. - The last subscript is stored in ''lastSub''. - ''delimiter$'' is specified by a regular expression. string$ = "hoge/piyo/foo/bar" delimiter$ = "/" 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 clearinfo for i from 0 to lastSub hop$ = arr$[i] printline 'i''tab$''hop$' endfor -- Unimportant note: '''hoge''' and '''piyo''', which appear in the first line of the script, are metasyntactic variables widely used in Japan, comparable to '''foo''' and '''bar''' in English. - Result: 0 hoge 1 piyo 2 foo 3 bar - '''Cf.''' An equivalent Perl Script: $string = "hoge/piyo/foo/bar"; $delimiter = "/"; @arr = split(/$delimiter/,$string); for ( $i = 0 ; $i <= $#arr ; $i++ ) { print "$i\t$arr[$i]\n"; } - 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. -- 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] # 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 select selectedID[1] for i from 2 to selectedObjectNum plus selectedID[i] endfor endif