[[FrontPage]]
#counter
* Praat Script Tips [#s823a6ce]

//- 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.
//- Most of them works at all.

#contents

** Emulation of Perl's $`, $&, and $' [#z1b70bdd]
- Extract the substring matched with a regular expression.

 string$ = "abcdefg"
 regex$ = "b"
 
 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 ==============================

- Result:

 original : abcdefg
          : abcdefg
 ==============================
 regex    : b
 ==============================
 prematch : a
 match    : b
 postmatch: cdefg
 ==============================

- '''Cf.''' An equivalent perl script:

 $string = "abcdefg";
 $regex = "b";
 
 $string =~ m/$regex/;
 print "$`\t$&\t$'\n";

** 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)

** 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''.
- ''delimiter$'' is specified by a regular expression.

 string$ = "hoge/piyo/foo/bar"
 delimiter$ = "/"
 
 if index_regex("",delimiter$) = 1
     lastSub = length(string$)-1
     tmp$ = replace_regex$(string$,delimiter$,"",0)
     lastSub = length(tmp$)-1
     for i from 0 to lastSub
         arr$[i] = mid$(string$,i+1,1)
         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

- 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

** 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


Front page   New List of pages Search Recent changes   Help   RSS of recent changes