The name is meant to evoke dplyr::bind_rows()
which "stacks" one dataframe
on top of another. Here we pull selected tiers from one textgrid and bind
them onto another other one.
Format
A Praat script
- textgrid_receiver
path of the textgrid file to update (attach tiers onto)
- textgrid_sender
path of the textgrid file to extract tiers from
- tiers_to_pull
comma-separated names of tiers to extract
- textgrid_out
path of the textgrid file to create
Example usage
library(tjm.praat)
# The two textgrids we want to bind together
tg <- system.file(
"demo-textgrids/birdhouse.TextGrid",
package = "tjm.praat"
)
tg_data <- readtextgrid::read_textgrid(tg)
tg2 <- system.file(
"demo-textgrids/birdhouse2.TextGrid",
package = "tjm.praat"
)
tg2_data <- readtextgrid::read_textgrid(tg2)
tg_out <- tempfile("test", fileext = ".TextGrid")
# We want to put "p2fa-words" and "p2fa-phones" on to the first textgrid
unique(tg_data$tier_name)
#> [1] "words" "phones"
unique(tg2_data$tier_name)
#> [1] "p2fa-words" "p2fa-phones"
f_bind_tiers <- wrap_praat_script(
script_code_to_run = bind_tiers,
returning = "last-argument"
)
tg_out <- f_bind_tiers(tg, tg2, "p2fa-words,p2fa-phones", tg_out)
tg_out_data <- readtextgrid::read_textgrid(tg_out)
unique(tg_out_data$tier_name)
#> [1] "words" "phones" "p2fa-words" "p2fa-phones"
Praat source code
print(f_bind_tiers, condense = FALSE)
function (textgrid_receiver = NULL, textgrid_sender = NULL, tiers_to_pull =
NULL, textgrid_out = NULL)
# <wrapped_praat_script>
# returning: "last-argument"
form Copy tiers from one textgrid (sender) onto another (reciever)
sentence Textgrid_receiver
sentence Textgrid_sender
sentence Tiers_to_pull
sentence Textgrid_out
endform
Read from file: textgrid_receiver$
id_tg_receiver = selected("TextGrid")
Read from file: textgrid_sender$
id_tg_sender = selected("TextGrid")
Create Strings as tokens: tiers_to_pull$, ","
id_str_tiers_to_pull = selected("Strings")
@stringsIter: "tiers", id_str_tiers_to_pull, "initialize"
while stringsIter.tiers.has_next
@stringsIter("tiers", id_str_tiers_to_pull, "next")
selectObject: id_tg_sender
# Pull tier
@findNumberForTier: stringsIter.tiers.next$
Extract one tier: findNumberForTier.result
id_tier = selected("TextGrid")
# Bind it
selectObject: id_tg_receiver
plusObject: id_tier
Merge
id_tg_temp = selected("TextGrid")
# Clean up
selectObject: id_tg_receiver
plusObject: id_tier
Remove
id_tg_receiver = id_tg_temp
endwhile
selectObject: id_tg_receiver
Save as text file: textgrid_out$
# Find the number of the (last) tier with a given name
procedure findNumberForTier: .target_tier$
.tiers = Get number of tiers
.result = 0
for .tier_i to .tiers
.tier_i_name$ = Get tier name: .tier_i
if .tier_i_name$ == .target_tier$
.result = .tier_i
endif
endfor
endproc
# An iterator for a list of strings
procedure stringsIter: .iter_name$, .id, .method$
selectObject: .id
# create a private namespace for this strings list iterator
.list$ = .iter_name$
if .method$ = "initialize"
.'.list$'.length = Get number of strings
.'.list$'.index = 0
endif
if .method$ = "next"
.'.list$'.index = .'.list$'.index + 1
.'.list$'.next$ = Get string: .'.list$'.index
endif
if .method$ = "has_next"
# .has_next is updated whenever procedure is invoked
endif
if .'.list$'.index < .'.list$'.length
.'.list$'.has_next = 1
else
.'.list$'.has_next = 0
endif
endproc