#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


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