scriptingpraat

How to run Voice Report in a Praat script for a specific part of the sound?


I'm new to Praat scripting and I'm trying to extract Voice Report, but for a specific start/end time in the sound file instead of the whole file. From the handbook, this example is given:

voiceReport$ = Voice report: 0, 0, 75, 500, 1.3, 1.6, 0.03, 0.45
jitter = extractNumber (voiceReport$, "Jitter (local): ")
shimmer = extractNumber (voiceReport$, "Shimmer (local): ")
writeInfoLine: "Jitter = ", percent$ (jitter, 3), ", shimmer = ", percent$     (shimmer, 3)

This runs the voice report for the whole file.

From some other helpful examples, I was able to put together the following script which creates a TextGrid with "silent" and "sounding" tiers. I would like to run Voice Report on each of the sounding rows (beginsound and endsound are the markers).

form analysis
   sentence inputFile
endform 
   sound = Read from file: inputFile$
   selectObject: sound  
   soundname$ = selected$("Sound")
   soundid = selected("Sound")

   To TextGrid (silences)... 60 0.3 0.1 silent sounding
   textgridid = selected("TextGrid")
   select 'textgridid'
   silencetierid = Extract tier... 1
   silencetableid = Down to TableOfReal... sounding
   nsounding = Get number of rows
   npauses = 'nsounding'
   speakingtot = 0
   for ipause from 1 to npauses
      beginsound = Get value... 'ipause' 1
      endsound = Get value... 'ipause' 2
      speakingdur = 'endsound' - 'beginsound'
      speakingtot = 'speakingdur' + 'speakingtot'                        
      printline sounding 'beginsound' 'endsound'
      comment How to run Voice Report between beginsound and endsound?
   endfor

From what I understand, Voice Report can be run on either a TextGrid selection, or on a selection of Sound + Pitch + PointProcess objects. I'm not sure how I can add the Voice Report command to my for loop here. Any help/direction is much appreciated. Thanks.


Solution

  • Short answer

    The first two arguments in the Voice report... command you mention are the start and end time for the chunk to be used for the report. If you use 0 for both values, then Praat takes the whole sound, but you can specify whatever values you want.

    Long answer:

    Your script will be fastest if the required objects (the Sound, Pitch and PointProcess objects) are calculated once, because you can specify the time range. It'll also be fastest if you don't run it from an editor, but directly using objects.

    You also don't need to turn the TextGrid into a TableOfReal: you can just query the beginning and end times of the sounding intervals directly, by checking the contents of the label to make sure it's an interval you want.

    # Initial variables, just to make the parameters clearer
    pitch_min = 60
    pitch_max = 600
    time_step = 0.3
    silence_threshold = -25
    min_pause = 0.1
    min_voiced = 0.1
    tier = 1
    
    # Detect silences
    sound = selected("Sound")
    textgrid = To TextGrid (silences): pitch_min, time_step, 
      ... silence_threshold, min_pause, min_voiced, "silent", "sounding"
    # The TextGrid is automatically selected
    total_intervals = Get number of intervals: tier
    
    # Make the remaining objects
    selectObject: sound
    pitch = To Pitch: 0, pitch_min, pitch_max
    selectObject: sound
    pulses = To PointProcess (periodic, cc): pitch_min, pitch_max
    
    # Find beginning and end of sounding intervals 
    for i to total_intervals
      selectObject: textgrid
      label$ = Get label of interval: tier, i
      if label$ == "sounding"
        start = Get start point: tier, i
        end   = Get end point: tier, i
        selectObject: sound, pitch, pulses
        report$ = Voice report: start, end,
          ... pitch_min, pitch_max, 1.3, 1.6, 0.03, 0.45
        # Do whatever you want with the report
      endif
    endfor
    
    # Clean up
    removeObject: textgrid, pitch, pulses
    

    An aside

    Feel free to ignore this, but as an aside, you're also calculating a number of variables that you don't really need. In your script, sound and soundid hold the same value, and the same is true with textgrid and textgridid. And this:

    To TextGrid (silences)... 60 0.3 0.1 silent sounding
    textgridid = selected("TextGrid")
    

    can be turned to this

    textgridid = To TextGrid (silences): 60, 0.3, 0.1, "silent", "sounding"
    

    You're also mixing the "shorthand" and the new syntax styles, which is sure to confuse things. Prefer the new style.