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.
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.
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
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.