[[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.
-- 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 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 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[^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 last subscript is stored in ''lastSub''.
- ''delimiter$'' is specified by a regular expression.

 ### Version 1 (The subscripts start at 1)
 string$ = "hoge/piyo/foo/bar"
 delimiter$ = "/"
 
 if index_regex("",delimiter$) = 1
     tmp$ = replace_regex$(string$,delimiter$,"",0)
     lastSub = length(tmp$)
     for i to lastSub
         arr$[i] = mid$(tmp$,i,1)
     endfor
 else
     lastSub = 1
     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 to lastSub
     hop$ = arr$[i]
     printline 'i''tab$''hop$'
 endfor


 ### Version 0 (The subscripts start at 0)
 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]
&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


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