FrontPage

Counter: 3342, today: 1, yesterday: 0

Praat Script Tips

  • 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: filesample_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

  • The scripts presented below are of little use per se.
  • It is easy to see, however, how they work.

deselect_all

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

# 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

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

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 $'

  • 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

Modified July 24, 2012. It still has a bug, however*1.

call split "str" delimiter
  • 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.
    clearinfo
    
    foo$ = "hoge/piyo/foo/bar"
    
    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

Check your Praat Version

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

Get the path separator for your platform

  • Get the path separator for your platform, and
  • Rewrite the path.
    • You can write a script which works on any platforms.
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

Get the path and filename from a string

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

str$ = "ABCDEFG"

newstr$ = replace_regex$(str$,"[A-Z]","\L&",0)

echo 'newstr$'
  • Result:
abcdefg

Get the tiernumbers from tiernames

  • 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

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

*1 About the bug in the emulation of split. 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";}' )

Attach file: filesample_concat.TextGrid 379 download [Information]

Front page   Edit Unfreeze Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2012-07-24 (Tue) 12:44:13 (1852d)