1

I am stuck trying to figure out how to read the strings from a textgrid which is open in the window but not saved to the hard disk as a raw text file. My goal is to manipulate the strings and save them later.

I want to do something like this but don't really understand how the syntax would work.

tG$ = selectObject: selected$("TextGrid")
stringID = Read Strings from tG

numberOfStrings = Get number of strings
for stringNumber from 0 to numberOfStrings
    selectObject: stringID
    line$ = Get string: stringNumber
...
jja
  • 2,058
  • 14
  • 27
badner
  • 768
  • 2
  • 10
  • 31

2 Answers2

1

You need to loop through the intervals in the TextGrid and use appendFileLine to output the labels to a text file. For example:

# Your need to select the TextGrid manually, and it has only one tier (tier number 1)

outputFile$ = "~/Desktop/output.txt"

writeFile: outputFile$, ""                        ; start from an empty .txt

numberOfIntervals = Get number of intervals: 1    ; (this is tier 1)

for interval to numberOfIntervals
    label$ = Get label of interval: 1, interval
    if label$ != ""                               ; (we just want non-empty intervals)
        xmin = Get start time of interval: 1, interval
        xmax = Get end time of interval: 1, interval
        appendFileLine: outputFile$, "'label$''tab$''xmin''tab$''xmax'"
    endif
endfor

This script will output a .txt file with tab delimited values: label, xmin, xmax. You can change the appendFileLine arguments to your needs (tab$ is a predefined variable, which is... a tab).

Stefano
  • 1,405
  • 11
  • 21
  • yes that is great. My problem however is how to actually GET the TG strings and how to select the object in the window. I don't think my code I pasted here works because there is something I am missing about how to do this. – badner Jan 26 '17 at 09:47
  • I get: No object with name "audio1". Formula not run. Script line 8 not performed or completed: « tG$ = selectObject: selected$("TextGrid") » Menu command "Run" not completed – badner Jan 26 '17 at 09:49
  • this is because I have a Textgrid selected called audio1 but it needs to enter into the selected$ part somehow. – badner Jan 26 '17 at 09:50
  • I am not sure I understand what you have to do exactly. If when you say "get the tg strings" you mean "get the tg intervals lables", this is what the script above does. If instead you mean the actual lines in the raw TG file, then you need first to save the TG file to a plain text file and then read it in with `Read Strings from raw text file`. – Stefano Jan 26 '17 at 09:50
  • What is your specific aim? – Stefano Jan 26 '17 at 09:51
  • exactly. Maybe my terminalogy is incorrect but what I want to get are the timestamps xmin and xmax for each phone item in the tier and save this information in variables for each item on the tier. – badner Jan 26 '17 at 09:52
  • I want to save the edited time stamps open in the window to a new file that is not a textgrid – badner Jan 26 '17 at 09:53
  • Then you should use the builtin functions `Get start time of interval` and `Get end time of interval`, no need to read from the raw TG. :) I can update the code above if you wish. I hope I understood what you have to do! – Stefano Jan 26 '17 at 09:56
  • Please do! You are way ahead of me. Thanks! – badner Jan 26 '17 at 09:59
  • you say that the textgrid is selected but I am still getting an error. I think something is wrong with my syntax in tG$ = selectObject: selected$("TextGrid") – badner Jan 26 '17 at 12:16
  • I was able to fix it like this: "selectObject: 2" I think there is a better way to do this automatically without having to know the object number. Ideally I would like it to find the first textgrid in the list but, for now this works – badner Jan 26 '17 at 18:06
0

TextGrid labels are not directly translatable to a Strings object because, unlike a TextGrid, Strings objects do not have tiers. So you could have code that takes all of the labels of a specific tier in a TextGrid and pushes them into a Strings object.

0. Creating an empty Strings

The problem here is that Praat does not want you to populate Strings object yourself, so there is no Create empty Strings.... However, you can subvert one of the existing commands to do this:

Create Strings as tokens: ""

1. Pushing the labels to a Strings object

Now that we have an empty Strings to populate, we can get to work:

procedure labelsToStrings: .tier
  .textgrid = selected("TextGrid")

  # Make sure this works with interval and point tiers
  .item$ = if do("Is interval tier...", .tier) then
    ... "interval" else "point" fi

  # Make the empty Strings
  .strings = Create Strings as tokens: ""
  Rename: selected$("TextGrid")

  # Fetch each label, and insert it to the Strings object
  selectObject: .textgrid
  .n = do("Get number of " + .item$ + "s...", .tier)
  for .i to .n
    selectObject: .textgrid
    .label$ = do$("Get label of " + .item$ + "...", .tier, .i)

    # I assume you don't care about empty labels?
    if .label$ != ""
      selectObject: .strings
      Insert string: 0, .label$
    endif
  endfor

  # Make sure the new object is selected
  selectObject: .strings
endproc

2. Profit!

You can try it out:

synth = Create SpeechSynthesizer: "English", "default"
To Sound: "This is some text.", "yes"
sound    = selected("Sound")
textgrid = selected("TextGrid")

selectObject: textgrid
@labelsToStrings: 4

removeObject: sound, synth
View & Edit

3. Bonus

If you are interested in getting all the labels in a more manageable package, you might also be interested in the Index specified labels... command from the tgutils plugin, which I also wrote. (I know: I'm amazing at naming things).

That one does something similar to this, but instead of using a Strings object, it dumps all the labels to a Table, as well as the timestamp of points, or the start and end of intervals. And you can also specify subsets of labels to consider using a literal match or a regular expression.

With it, you can re-write @labelsToStrings to look like this:

procedure labelsToStrings: .tier
  .name$ = selected$("TextGrid")

  runScript: preferencesDirectory$ + "/plugin_tgutils/scripts/" +
    ... "index_specified_labels.praat", .tier, ".+", "yes"
  .table = selected("Table")

  Create Strings as tokens: ""
  Rename: .name$
  for .i to Object_'.table'.nrow
    .label$ = Object_'.table'$[.i, "label"]
    Insert string: 0, .label$
  endfor
  removeObject: .table
endproc
jja
  • 2,058
  • 14
  • 27